blob: bab12c89564fc2044b6a788255bec487e6168537 [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"
Jim Inghamebc09c32010-07-07 03:36:20 +000032
33using namespace lldb;
34using namespace lldb_private;
35
Jim Inghamebc09c32010-07-07 03:36:20 +000036//-------------------------------------------------------------------------
37// CommandObjectCommandsSource
38//-------------------------------------------------------------------------
39
Jim Ingham5a988412012-06-08 21:56:10 +000040class CommandObjectCommandsHistory : public CommandObjectParsed
Jim Inghama5a97eb2011-07-12 03:12:18 +000041{
Jim Ingham5a988412012-06-08 21:56:10 +000042public:
43 CommandObjectCommandsHistory(CommandInterpreter &interpreter) :
44 CommandObjectParsed (interpreter,
45 "command history",
46 "Dump the history of commands in this session.",
47 NULL),
48 m_options (interpreter)
49 {
50 }
51
52 ~CommandObjectCommandsHistory () {}
53
54 virtual Options *
55 GetOptions ()
56 {
57 return &m_options;
58 }
59
60protected:
Jim Inghama5a97eb2011-07-12 03:12:18 +000061
62 class CommandOptions : public Options
63 {
64 public:
65
66 CommandOptions (CommandInterpreter &interpreter) :
Enrico Granata7594f142013-06-17 22:51:50 +000067 Options (interpreter),
68 m_start_idx(0),
69 m_stop_idx(0),
70 m_count(0),
Enrico Granata63123b62013-06-17 23:28:27 +000071 m_clear(false)
Jim Inghama5a97eb2011-07-12 03:12:18 +000072 {
73 }
74
75 virtual
76 ~CommandOptions (){}
77
78 virtual Error
79 SetOptionValue (uint32_t option_idx, const char *option_arg)
80 {
81 Error error;
Greg Clayton3bcdfc02012-12-04 00:32:51 +000082 const int short_option = m_getopt_table[option_idx].val;
Jim Inghama5a97eb2011-07-12 03:12:18 +000083
84 switch (short_option)
85 {
86 case 'c':
Pavel Labathc95f7e22015-02-20 11:14:59 +000087 error = m_count.SetValueFromString(option_arg,eVarSetOperationAssign);
Jim Inghama5a97eb2011-07-12 03:12:18 +000088 break;
89 case 's':
Enrico Granata7594f142013-06-17 22:51:50 +000090 if (option_arg && strcmp("end", option_arg) == 0)
91 {
92 m_start_idx.SetCurrentValue(UINT64_MAX);
93 m_start_idx.SetOptionWasSet();
94 }
95 else
Pavel Labathc95f7e22015-02-20 11:14:59 +000096 error = m_start_idx.SetValueFromString(option_arg,eVarSetOperationAssign);
Enrico Granata7594f142013-06-17 22:51:50 +000097 break;
98 case 'e':
Pavel Labathc95f7e22015-02-20 11:14:59 +000099 error = m_stop_idx.SetValueFromString(option_arg,eVarSetOperationAssign);
Enrico Granata7594f142013-06-17 22:51:50 +0000100 break;
Enrico Granata63123b62013-06-17 23:28:27 +0000101 case 'C':
102 m_clear.SetCurrentValue(true);
103 m_clear.SetOptionWasSet();
Jim Inghama5a97eb2011-07-12 03:12:18 +0000104 break;
105 default:
Greg Clayton86edbf42011-10-26 00:56:27 +0000106 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
Jim Inghama5a97eb2011-07-12 03:12:18 +0000107 break;
108 }
109
110 return error;
111 }
112
113 void
114 OptionParsingStarting ()
115 {
Enrico Granata7594f142013-06-17 22:51:50 +0000116 m_start_idx.Clear();
117 m_stop_idx.Clear();
118 m_count.Clear();
Enrico Granata63123b62013-06-17 23:28:27 +0000119 m_clear.Clear();
Jim Inghama5a97eb2011-07-12 03:12:18 +0000120 }
121
122 const OptionDefinition*
123 GetDefinitions ()
124 {
125 return g_option_table;
126 }
127
128 // Options table: Required for subclasses of Options.
129
130 static OptionDefinition g_option_table[];
131
132 // Instance variables to hold the values for command options.
133
Enrico Granata7594f142013-06-17 22:51:50 +0000134 OptionValueUInt64 m_start_idx;
135 OptionValueUInt64 m_stop_idx;
136 OptionValueUInt64 m_count;
Enrico Granata63123b62013-06-17 23:28:27 +0000137 OptionValueBoolean m_clear;
Jim Inghama5a97eb2011-07-12 03:12:18 +0000138 };
139
Jim Inghama5a97eb2011-07-12 03:12:18 +0000140 bool
Jim Ingham5a988412012-06-08 21:56:10 +0000141 DoExecute (Args& command, CommandReturnObject &result)
Jim Inghama5a97eb2011-07-12 03:12:18 +0000142 {
Enrico Granata63123b62013-06-17 23:28:27 +0000143 if (m_options.m_clear.GetCurrentValue() && m_options.m_clear.OptionWasSet())
Enrico Granata7594f142013-06-17 22:51:50 +0000144 {
145 m_interpreter.GetCommandHistory().Clear();
146 result.SetStatus(lldb::eReturnStatusSuccessFinishNoResult);
147 }
148 else
149 {
150 if (m_options.m_start_idx.OptionWasSet() && m_options.m_stop_idx.OptionWasSet() && m_options.m_count.OptionWasSet())
151 {
152 result.AppendError("--count, --start-index and --end-index cannot be all specified in the same invocation");
153 result.SetStatus(lldb::eReturnStatusFailed);
154 }
155 else
156 {
Virgile Bello84400ec2013-08-27 16:22:29 +0000157 std::pair<bool,uint64_t> start_idx(m_options.m_start_idx.OptionWasSet(),m_options.m_start_idx.GetCurrentValue());
158 std::pair<bool,uint64_t> stop_idx(m_options.m_stop_idx.OptionWasSet(),m_options.m_stop_idx.GetCurrentValue());
159 std::pair<bool,uint64_t> count(m_options.m_count.OptionWasSet(),m_options.m_count.GetCurrentValue());
Enrico Granata7594f142013-06-17 22:51:50 +0000160
161 const CommandHistory& history(m_interpreter.GetCommandHistory());
162
163 if (start_idx.first && start_idx.second == UINT64_MAX)
164 {
165 if (count.first)
166 {
167 start_idx.second = history.GetSize() - count.second;
168 stop_idx.second = history.GetSize() - 1;
169 }
170 else if (stop_idx.first)
171 {
172 start_idx.second = stop_idx.second;
173 stop_idx.second = history.GetSize() - 1;
174 }
175 else
176 {
177 start_idx.second = 0;
178 stop_idx.second = history.GetSize() - 1;
179 }
180 }
181 else
182 {
183 if (!start_idx.first && !stop_idx.first && !count.first)
184 {
185 start_idx.second = 0;
186 stop_idx.second = history.GetSize() - 1;
187 }
188 else if (start_idx.first)
189 {
190 if (count.first)
191 {
192 stop_idx.second = start_idx.second + count.second - 1;
193 }
194 else if (!stop_idx.first)
195 {
196 stop_idx.second = history.GetSize() - 1;
197 }
198 }
199 else if (stop_idx.first)
200 {
201 if (count.first)
202 {
203 if (stop_idx.second >= count.second)
204 start_idx.second = stop_idx.second - count.second + 1;
205 else
206 start_idx.second = 0;
207 }
208 }
209 else /* if (count.first) */
210 {
211 start_idx.second = 0;
212 stop_idx.second = count.second - 1;
213 }
214 }
215 history.Dump(result.GetOutputStream(), start_idx.second, stop_idx.second);
216 }
217 }
Jim Inghama5a97eb2011-07-12 03:12:18 +0000218 return result.Succeeded();
219
220 }
Jim Ingham5a988412012-06-08 21:56:10 +0000221
222 CommandOptions m_options;
Jim Inghama5a97eb2011-07-12 03:12:18 +0000223};
224
225OptionDefinition
226CommandObjectCommandsHistory::CommandOptions::g_option_table[] =
227{
Zachary Turnerd37221d2014-07-09 16:31:49 +0000228{ LLDB_OPT_SET_1, false, "count", 'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeUnsignedInteger, "How many history commands to print."},
229{ LLDB_OPT_SET_1, false, "start-index", 's', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeUnsignedInteger, "Index at which to start printing history commands (or end to mean tail mode)."},
230{ LLDB_OPT_SET_1, false, "end-index", 'e', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeUnsignedInteger, "Index at which to stop printing history commands."},
231{ LLDB_OPT_SET_2, false, "clear", 'C', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeBoolean, "Clears the current command history."},
232{ 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
Jim Inghama5a97eb2011-07-12 03:12:18 +0000233};
234
235
236//-------------------------------------------------------------------------
237// CommandObjectCommandsSource
238//-------------------------------------------------------------------------
239
Jim Ingham5a988412012-06-08 21:56:10 +0000240class CommandObjectCommandsSource : public CommandObjectParsed
Jim Inghamebc09c32010-07-07 03:36:20 +0000241{
Jim Ingham5a988412012-06-08 21:56:10 +0000242public:
243 CommandObjectCommandsSource(CommandInterpreter &interpreter) :
244 CommandObjectParsed (interpreter,
245 "command source",
246 "Read in debugger commands from the file <filename> and execute them.",
247 NULL),
248 m_options (interpreter)
249 {
250 CommandArgumentEntry arg;
251 CommandArgumentData file_arg;
252
253 // Define the first (and only) variant of this arg.
254 file_arg.arg_type = eArgTypeFilename;
255 file_arg.arg_repetition = eArgRepeatPlain;
256
257 // There is only one variant this argument could be; put it into the argument entry.
258 arg.push_back (file_arg);
259
260 // Push the data for the first argument into the m_arguments vector.
261 m_arguments.push_back (arg);
262 }
263
264 ~CommandObjectCommandsSource () {}
265
266 virtual const char*
267 GetRepeatCommand (Args &current_command_args, uint32_t index)
268 {
269 return "";
270 }
271
Greg Claytonc7bece562013-01-25 18:06:21 +0000272 virtual int
Jim Ingham5a988412012-06-08 21:56:10 +0000273 HandleArgumentCompletion (Args &input,
274 int &cursor_index,
275 int &cursor_char_position,
276 OptionElementVector &opt_element_vector,
277 int match_start_point,
278 int max_return_elements,
279 bool &word_complete,
280 StringList &matches)
281 {
282 std::string completion_str (input.GetArgumentAtIndex(cursor_index));
283 completion_str.erase (cursor_char_position);
284
285 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
286 CommandCompletions::eDiskFileCompletion,
287 completion_str.c_str(),
288 match_start_point,
289 max_return_elements,
290 NULL,
291 word_complete,
292 matches);
293 return matches.GetSize();
294 }
295
296 virtual Options *
297 GetOptions ()
298 {
299 return &m_options;
300 }
301
302protected:
Jim Inghame16c50a2011-02-18 00:54:25 +0000303
304 class CommandOptions : public Options
305 {
306 public:
307
Greg Claytoneb0103f2011-04-07 22:46:35 +0000308 CommandOptions (CommandInterpreter &interpreter) :
Enrico Granata012d4fc2013-06-11 01:26:35 +0000309 Options (interpreter),
Greg Clayton340b0302014-02-05 17:57:57 +0000310 m_stop_on_error (true),
311 m_silent_run (false),
312 m_stop_on_continue (true)
Greg Claytoneb0103f2011-04-07 22:46:35 +0000313 {
314 }
Jim Inghame16c50a2011-02-18 00:54:25 +0000315
316 virtual
317 ~CommandOptions (){}
318
319 virtual Error
Greg Claytonf6b8b582011-04-13 00:18:08 +0000320 SetOptionValue (uint32_t option_idx, const char *option_arg)
Jim Inghame16c50a2011-02-18 00:54:25 +0000321 {
322 Error error;
Greg Clayton3bcdfc02012-12-04 00:32:51 +0000323 const int short_option = m_getopt_table[option_idx].val;
Jim Inghame16c50a2011-02-18 00:54:25 +0000324
325 switch (short_option)
326 {
327 case 'e':
Pavel Labathc95f7e22015-02-20 11:14:59 +0000328 error = m_stop_on_error.SetValueFromString(option_arg);
Jim Inghame16c50a2011-02-18 00:54:25 +0000329 break;
Greg Clayton340b0302014-02-05 17:57:57 +0000330
Jim Inghame16c50a2011-02-18 00:54:25 +0000331 case 'c':
Pavel Labathc95f7e22015-02-20 11:14:59 +0000332 error = m_stop_on_continue.SetValueFromString(option_arg);
Jim Inghame16c50a2011-02-18 00:54:25 +0000333 break;
Greg Clayton340b0302014-02-05 17:57:57 +0000334
Michael Sartain60986172013-07-09 23:22:53 +0000335 case 's':
Pavel Labathc95f7e22015-02-20 11:14:59 +0000336 error = m_silent_run.SetValueFromString(option_arg);
Michael Sartain60986172013-07-09 23:22:53 +0000337 break;
Greg Clayton340b0302014-02-05 17:57:57 +0000338
Jim Inghame16c50a2011-02-18 00:54:25 +0000339 default:
Greg Clayton86edbf42011-10-26 00:56:27 +0000340 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
Jim Inghame16c50a2011-02-18 00:54:25 +0000341 break;
342 }
343
344 return error;
345 }
346
347 void
Greg Claytonf6b8b582011-04-13 00:18:08 +0000348 OptionParsingStarting ()
Jim Inghame16c50a2011-02-18 00:54:25 +0000349 {
Enrico Granata012d4fc2013-06-11 01:26:35 +0000350 m_stop_on_error.Clear();
Greg Clayton340b0302014-02-05 17:57:57 +0000351 m_silent_run.Clear();
352 m_stop_on_continue.Clear();
Jim Inghame16c50a2011-02-18 00:54:25 +0000353 }
354
Greg Claytone0d378b2011-03-24 21:19:54 +0000355 const OptionDefinition*
Jim Inghame16c50a2011-02-18 00:54:25 +0000356 GetDefinitions ()
357 {
358 return g_option_table;
359 }
360
361 // Options table: Required for subclasses of Options.
362
Greg Claytone0d378b2011-03-24 21:19:54 +0000363 static OptionDefinition g_option_table[];
Jim Inghame16c50a2011-02-18 00:54:25 +0000364
365 // Instance variables to hold the values for command options.
366
Enrico Granata012d4fc2013-06-11 01:26:35 +0000367 OptionValueBoolean m_stop_on_error;
Jim Ingham7d8555c2014-11-18 19:12:13 +0000368 OptionValueBoolean m_silent_run;
Greg Clayton340b0302014-02-05 17:57:57 +0000369 OptionValueBoolean m_stop_on_continue;
Jim Inghame16c50a2011-02-18 00:54:25 +0000370 };
371
Jim Inghamebc09c32010-07-07 03:36:20 +0000372 bool
Jim Ingham5a988412012-06-08 21:56:10 +0000373 DoExecute(Args& command, CommandReturnObject &result)
Jim Inghamebc09c32010-07-07 03:36:20 +0000374 {
Greg Claytonc7bece562013-01-25 18:06:21 +0000375 const size_t argc = command.GetArgumentCount();
Jim Inghamebc09c32010-07-07 03:36:20 +0000376 if (argc == 1)
377 {
Jim Ingham5a988412012-06-08 21:56:10 +0000378 const char *filename = command.GetArgumentAtIndex(0);
Jim Inghamebc09c32010-07-07 03:36:20 +0000379
Johnny Chen1ee38532010-10-20 21:40:50 +0000380 FileSpec cmd_file (filename, true);
Jim Inghame16c50a2011-02-18 00:54:25 +0000381 ExecutionContext *exe_ctx = NULL; // Just use the default context.
Greg Clayton340b0302014-02-05 17:57:57 +0000382
383 // If any options were set, then use them
384 if (m_options.m_stop_on_error.OptionWasSet() ||
385 m_options.m_silent_run.OptionWasSet() ||
386 m_options.m_stop_on_continue.OptionWasSet())
387 {
388 // Use user set settings
Jim Ingham26c7bf92014-10-11 00:38:27 +0000389 CommandInterpreterRunOptions options;
390 options.SetStopOnContinue(m_options.m_stop_on_continue.GetCurrentValue());
391 options.SetStopOnError (m_options.m_stop_on_error.GetCurrentValue());
Jim Ingham7d8555c2014-11-18 19:12:13 +0000392 options.SetEchoCommands (!m_options.m_silent_run.GetCurrentValue());
393 options.SetPrintResults (!m_options.m_silent_run.GetCurrentValue());
Jim Ingham26c7bf92014-10-11 00:38:27 +0000394
Greg Clayton340b0302014-02-05 17:57:57 +0000395 m_interpreter.HandleCommandsFromFile (cmd_file,
396 exe_ctx,
Jim Ingham26c7bf92014-10-11 00:38:27 +0000397 options,
Greg Clayton340b0302014-02-05 17:57:57 +0000398 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...
Jim Ingham26c7bf92014-10-11 00:38:27 +0000405 CommandInterpreterRunOptions options;
Greg Clayton340b0302014-02-05 17:57:57 +0000406 m_interpreter.HandleCommandsFromFile (cmd_file,
407 exe_ctx,
Jim Ingham26c7bf92014-10-11 00:38:27 +0000408 options,
Greg Clayton340b0302014-02-05 17:57:57 +0000409 result);
410
411 }
Jim Inghamebc09c32010-07-07 03:36:20 +0000412 }
413 else
414 {
415 result.AppendErrorWithFormat("'%s' takes exactly one executable filename argument.\n", GetCommandName());
416 result.SetStatus (eReturnStatusFailed);
417 }
418 return result.Succeeded();
419
420 }
Jim Ingham5a988412012-06-08 21:56:10 +0000421 CommandOptions m_options;
Jim Inghamebc09c32010-07-07 03:36:20 +0000422};
423
Greg Claytone0d378b2011-03-24 21:19:54 +0000424OptionDefinition
Jim Inghame16c50a2011-02-18 00:54:25 +0000425CommandObjectCommandsSource::CommandOptions::g_option_table[] =
426{
Zachary Turnerd37221d2014-07-09 16:31:49 +0000427{ LLDB_OPT_SET_ALL, false, "stop-on-error", 'e', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "If true, stop executing commands on error."},
428{ LLDB_OPT_SET_ALL, false, "stop-on-continue", 'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "If true, stop executing commands on continue."},
429{ LLDB_OPT_SET_ALL, false, "silent-run", 's', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "If true don't echo commands while executing."},
430{ 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
Jim Inghame16c50a2011-02-18 00:54:25 +0000431};
432
Jim Inghamebc09c32010-07-07 03:36:20 +0000433#pragma mark CommandObjectCommandsAlias
434//-------------------------------------------------------------------------
435// CommandObjectCommandsAlias
436//-------------------------------------------------------------------------
437
Enrico Granatabe93a352011-08-16 16:49:25 +0000438static const char *g_python_command_instructions = "Enter your Python command(s). Type 'DONE' to end.\n"
439 "You must define a Python function with this signature:\n"
Greg Clayton44d93782014-01-27 23:43:24 +0000440 "def my_command_impl(debugger, args, result, internal_dict):\n";
Enrico Granatabe93a352011-08-16 16:49:25 +0000441
442
Jim Ingham5a988412012-06-08 21:56:10 +0000443class CommandObjectCommandsAlias : public CommandObjectRaw
Jim Inghamebc09c32010-07-07 03:36:20 +0000444{
Enrico Granatabe93a352011-08-16 16:49:25 +0000445
Enrico Granatabe93a352011-08-16 16:49:25 +0000446
Jim Inghamebc09c32010-07-07 03:36:20 +0000447public:
Greg Claytona7015092010-09-18 01:14:36 +0000448 CommandObjectCommandsAlias (CommandInterpreter &interpreter) :
Jim Ingham5a988412012-06-08 21:56:10 +0000449 CommandObjectRaw (interpreter,
Greg Clayton0e5e5a72011-04-20 22:55:21 +0000450 "command alias",
Caroline Ticee3d26312010-09-08 21:06:11 +0000451 "Allow users to define their own debugger command abbreviations.",
Caroline Tice405fe672010-10-04 22:28:36 +0000452 NULL)
Jim Inghamebc09c32010-07-07 03:36:20 +0000453 {
454 SetHelpLong(
455 "'alias' allows the user to create a short-cut or abbreviation for long \n\
456 commands, multi-word commands, and commands that take particular options. \n\
457 Below are some simple examples of how one might use the 'alias' command: \n\
Jason Molenda69c12cc2011-11-10 22:43:35 +0000458 \n 'command alias sc script' // Creates the abbreviation 'sc' for the 'script' \n\
Caroline Tice09799af2010-09-08 22:08:58 +0000459 // command. \n\
Jason Molenda69c12cc2011-11-10 22:43:35 +0000460 'command alias bp breakpoint' // Creates the abbreviation 'bp' for the 'breakpoint' \n\
Caroline Tice09799af2010-09-08 22:08:58 +0000461 // command. Since breakpoint commands are two-word \n\
462 // commands, the user will still need to enter the \n\
463 // second word after 'bp', e.g. 'bp enable' or \n\
464 // 'bp delete'. \n\
Jason Molenda69c12cc2011-11-10 22:43:35 +0000465 'command alias bpl breakpoint list' // Creates the abbreviation 'bpl' for the \n\
Caroline Tice09799af2010-09-08 22:08:58 +0000466 // two-word command 'breakpoint list'. \n\
Jim Inghamebc09c32010-07-07 03:36:20 +0000467 \nAn alias can include some options for the command, with the values either \n\
468 filled in at the time the alias is created, or specified as positional \n\
469 arguments, to be filled in when the alias is invoked. The following example \n\
470 shows how to create aliases with options: \n\
471 \n\
Jason Molenda69c12cc2011-11-10 22:43:35 +0000472 'command alias bfl breakpoint set -f %1 -l %2' \n\
Jim Inghamebc09c32010-07-07 03:36:20 +0000473 \nThis creates the abbreviation 'bfl' (for break-file-line), with the -f and -l \n\
474 options already part of the alias. So if the user wants to set a breakpoint \n\
475 by file and line without explicitly having to use the -f and -l options, the \n\
476 user can now use 'bfl' instead. The '%1' and '%2' are positional placeholders \n\
477 for the actual arguments that will be passed when the alias command is used. \n\
478 The number in the placeholder refers to the position/order the actual value \n\
Jim Ingham81ded932011-08-18 02:29:05 +0000479 occupies when the alias is used. All the occurrences of '%1' in the alias \n\
Jim Inghamebc09c32010-07-07 03:36:20 +0000480 will be replaced with the first argument, all the occurrences of '%2' in the \n\
481 alias will be replaced with the second argument, and so on. This also allows \n\
482 actual arguments to be used multiple times within an alias (see 'process \n\
Jim Ingham81ded932011-08-18 02:29:05 +0000483 launch' example below). \n\
484 Note: the positional arguments must substitute as whole words in the resultant\n\
485 command, so you can't at present do something like:\n\
486 \n\
Jason Molenda69c12cc2011-11-10 22:43:35 +0000487 command alias bcppfl breakpoint set -f %1.cpp -l %2\n\
Jim Ingham81ded932011-08-18 02:29:05 +0000488 \n\
489 to get the file extension \".cpp\" automatically appended. For more complex\n\
490 aliasing, use the \"command regex\" command instead.\n\
491 \nSo in the 'bfl' case, the actual file value will be \n\
Jim Inghamebc09c32010-07-07 03:36:20 +0000492 filled in with the first argument following 'bfl' and the actual line number \n\
493 value will be filled in with the second argument. The user would use this \n\
494 alias as follows: \n\
Jason Molenda69c12cc2011-11-10 22:43:35 +0000495 \n (lldb) command alias bfl breakpoint set -f %1 -l %2 \n\
Sean Callanan0708e2c2010-08-09 18:50:15 +0000496 <... some time later ...> \n\
Caroline Tice09799af2010-09-08 22:08:58 +0000497 (lldb) bfl my-file.c 137 \n\
Jim Inghamebc09c32010-07-07 03:36:20 +0000498 \nThis would be the same as if the user had entered \n\
499 'breakpoint set -f my-file.c -l 137'. \n\
500 \nAnother example: \n\
Jason Molenda69c12cc2011-11-10 22:43:35 +0000501 \n (lldb) command alias pltty process launch -s -o %1 -e %1 \n\
Caroline Tice09799af2010-09-08 22:08:58 +0000502 (lldb) pltty /dev/tty0 \n\
Sean Callanan0708e2c2010-08-09 18:50:15 +0000503 // becomes 'process launch -s -o /dev/tty0 -e /dev/tty0' \n\
Jim Inghamebc09c32010-07-07 03:36:20 +0000504 \nIf the user always wanted to pass the same value to a particular option, the \n\
505 alias could be defined with that value directly in the alias as a constant, \n\
506 rather than using a positional placeholder: \n\
Jason Molenda69c12cc2011-11-10 22:43:35 +0000507 \n command alias bl3 breakpoint set -f %1 -l 3 // Always sets a breakpoint on line \n\
Sean Callanan0708e2c2010-08-09 18:50:15 +0000508 // 3 of whatever file is indicated. \n");
Jim Inghamebc09c32010-07-07 03:36:20 +0000509
Caroline Tice405fe672010-10-04 22:28:36 +0000510 CommandArgumentEntry arg1;
511 CommandArgumentEntry arg2;
512 CommandArgumentEntry arg3;
513 CommandArgumentData alias_arg;
514 CommandArgumentData cmd_arg;
515 CommandArgumentData options_arg;
516
517 // Define the first (and only) variant of this arg.
518 alias_arg.arg_type = eArgTypeAliasName;
519 alias_arg.arg_repetition = eArgRepeatPlain;
520
521 // There is only one variant this argument could be; put it into the argument entry.
522 arg1.push_back (alias_arg);
523
524 // Define the first (and only) variant of this arg.
525 cmd_arg.arg_type = eArgTypeCommandName;
526 cmd_arg.arg_repetition = eArgRepeatPlain;
527
528 // There is only one variant this argument could be; put it into the argument entry.
529 arg2.push_back (cmd_arg);
530
531 // Define the first (and only) variant of this arg.
532 options_arg.arg_type = eArgTypeAliasOptions;
533 options_arg.arg_repetition = eArgRepeatOptional;
534
535 // There is only one variant this argument could be; put it into the argument entry.
536 arg3.push_back (options_arg);
537
538 // Push the data for the first argument into the m_arguments vector.
539 m_arguments.push_back (arg1);
540 m_arguments.push_back (arg2);
541 m_arguments.push_back (arg3);
Jim Inghamebc09c32010-07-07 03:36:20 +0000542 }
543
544 ~CommandObjectCommandsAlias ()
545 {
546 }
547
Jim Ingham5a988412012-06-08 21:56:10 +0000548protected:
549 virtual bool
550 DoExecute (const char *raw_command_line, CommandReturnObject &result)
Caroline Tice844d2302010-12-09 22:52:49 +0000551 {
552 Args args (raw_command_line);
553 std::string raw_command_string (raw_command_line);
554
555 size_t argc = args.GetArgumentCount();
556
557 if (argc < 2)
558 {
559 result.AppendError ("'alias' requires at least two arguments");
560 result.SetStatus (eReturnStatusFailed);
561 return false;
562 }
563
564 // Get the alias command.
565
566 const std::string alias_command = args.GetArgumentAtIndex (0);
Enrico Granatabe93a352011-08-16 16:49:25 +0000567
Caroline Tice844d2302010-12-09 22:52:49 +0000568 // Strip the new alias name off 'raw_command_string' (leave it on args, which gets passed to 'Execute', which
569 // does the stripping itself.
570 size_t pos = raw_command_string.find (alias_command);
571 if (pos == 0)
572 {
573 raw_command_string = raw_command_string.substr (alias_command.size());
574 pos = raw_command_string.find_first_not_of (' ');
575 if ((pos != std::string::npos) && (pos > 0))
576 raw_command_string = raw_command_string.substr (pos);
577 }
578 else
579 {
580 result.AppendError ("Error parsing command string. No alias created.");
581 result.SetStatus (eReturnStatusFailed);
582 return false;
583 }
584
585
586 // Verify that the command is alias-able.
587 if (m_interpreter.CommandExists (alias_command.c_str()))
588 {
589 result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be redefined.\n",
590 alias_command.c_str());
591 result.SetStatus (eReturnStatusFailed);
592 return false;
593 }
594
595 // Get CommandObject that is being aliased. The command name is read from the front of raw_command_string.
596 // raw_command_string is returned with the name of the command object stripped off the front.
597 CommandObject *cmd_obj = m_interpreter.GetCommandObjectForCommand (raw_command_string);
598
599 if (!cmd_obj)
600 {
Greg Clayton86edbf42011-10-26 00:56:27 +0000601 result.AppendErrorWithFormat ("invalid command given to 'alias'. '%s' does not begin with a valid command."
Caroline Tice844d2302010-12-09 22:52:49 +0000602 " No alias created.", raw_command_string.c_str());
603 result.SetStatus (eReturnStatusFailed);
604 return false;
605 }
606 else if (!cmd_obj->WantsRawCommandString ())
607 {
608 // Note that args was initialized with the original command, and has not been updated to this point.
609 // 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 +0000610 return HandleAliasingNormalCommand (args, result);
Caroline Tice844d2302010-12-09 22:52:49 +0000611 }
612 else
613 {
Jim Ingham5a988412012-06-08 21:56:10 +0000614 return HandleAliasingRawCommand (alias_command, raw_command_string, *cmd_obj, result);
615 }
616 return result.Succeeded();
617 }
618
619 bool
620 HandleAliasingRawCommand (const std::string &alias_command, std::string &raw_command_string, CommandObject &cmd_obj, CommandReturnObject &result)
621 {
Caroline Tice844d2302010-12-09 22:52:49 +0000622 // Verify & handle any options/arguments passed to the alias command
623
624 OptionArgVectorSP option_arg_vector_sp = OptionArgVectorSP (new OptionArgVector);
625 OptionArgVector *option_arg_vector = option_arg_vector_sp.get();
626
Jim Ingham5a988412012-06-08 21:56:10 +0000627 CommandObjectSP cmd_obj_sp = m_interpreter.GetCommandSPExact (cmd_obj.GetCommandName(), false);
Caroline Ticeca90c472011-05-06 21:37:15 +0000628
629 if (!m_interpreter.ProcessAliasOptionsArgs (cmd_obj_sp, raw_command_string.c_str(), option_arg_vector_sp))
Caroline Tice844d2302010-12-09 22:52:49 +0000630 {
Caroline Ticeca90c472011-05-06 21:37:15 +0000631 result.AppendError ("Unable to create requested alias.\n");
632 result.SetStatus (eReturnStatusFailed);
633 return false;
Caroline Tice844d2302010-12-09 22:52:49 +0000634 }
635
636 // Create the alias
637 if (m_interpreter.AliasExists (alias_command.c_str())
638 || m_interpreter.UserCommandExists (alias_command.c_str()))
639 {
640 OptionArgVectorSP temp_option_arg_sp (m_interpreter.GetAliasOptions (alias_command.c_str()));
641 if (temp_option_arg_sp.get())
642 {
643 if (option_arg_vector->size() == 0)
644 m_interpreter.RemoveAliasOptions (alias_command.c_str());
645 }
646 result.AppendWarningWithFormat ("Overwriting existing definition for '%s'.\n",
647 alias_command.c_str());
648 }
649
Caroline Tice472362e2010-12-14 18:51:39 +0000650 if (cmd_obj_sp)
651 {
652 m_interpreter.AddAlias (alias_command.c_str(), cmd_obj_sp);
653 if (option_arg_vector->size() > 0)
654 m_interpreter.AddOrReplaceAliasOptions (alias_command.c_str(), option_arg_vector_sp);
655 result.SetStatus (eReturnStatusSuccessFinishNoResult);
656 }
657 else
658 {
659 result.AppendError ("Unable to create requested alias.\n");
660 result.SetStatus (eReturnStatusFailed);
661 }
Jim Ingham5a988412012-06-08 21:56:10 +0000662 return result.Succeeded ();
Caroline Tice844d2302010-12-09 22:52:49 +0000663 }
Jim Ingham5a988412012-06-08 21:56:10 +0000664
Jim Inghamebc09c32010-07-07 03:36:20 +0000665 bool
Jim Ingham5a988412012-06-08 21:56:10 +0000666 HandleAliasingNormalCommand (Args& args, CommandReturnObject &result)
Jim Inghamebc09c32010-07-07 03:36:20 +0000667 {
Caroline Tice867b185d2010-09-21 23:25:40 +0000668 size_t argc = args.GetArgumentCount();
Jim Inghamebc09c32010-07-07 03:36:20 +0000669
670 if (argc < 2)
Greg Claytonc982c762010-07-09 20:39:50 +0000671 {
Jim Inghamebc09c32010-07-07 03:36:20 +0000672 result.AppendError ("'alias' requires at least two arguments");
673 result.SetStatus (eReturnStatusFailed);
674 return false;
Greg Claytonc982c762010-07-09 20:39:50 +0000675 }
Jim Inghamebc09c32010-07-07 03:36:20 +0000676
677 const std::string alias_command = args.GetArgumentAtIndex(0);
678 const std::string actual_command = args.GetArgumentAtIndex(1);
679
680 args.Shift(); // Shift the alias command word off the argument vector.
681 args.Shift(); // Shift the old command word off the argument vector.
682
683 // Verify that the command is alias'able, and get the appropriate command object.
684
Greg Claytona7015092010-09-18 01:14:36 +0000685 if (m_interpreter.CommandExists (alias_command.c_str()))
Jim Inghamebc09c32010-07-07 03:36:20 +0000686 {
687 result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be redefined.\n",
688 alias_command.c_str());
689 result.SetStatus (eReturnStatusFailed);
690 }
691 else
692 {
Greg Claytona7015092010-09-18 01:14:36 +0000693 CommandObjectSP command_obj_sp(m_interpreter.GetCommandSPExact (actual_command.c_str(), true));
Jim Inghamebc09c32010-07-07 03:36:20 +0000694 CommandObjectSP subcommand_obj_sp;
695 bool use_subcommand = false;
696 if (command_obj_sp.get())
697 {
698 CommandObject *cmd_obj = command_obj_sp.get();
Greg Claytonc982c762010-07-09 20:39:50 +0000699 CommandObject *sub_cmd_obj = NULL;
Jim Inghamebc09c32010-07-07 03:36:20 +0000700 OptionArgVectorSP option_arg_vector_sp = OptionArgVectorSP (new OptionArgVector);
701 OptionArgVector *option_arg_vector = option_arg_vector_sp.get();
702
Caroline Tice844d2302010-12-09 22:52:49 +0000703 while (cmd_obj->IsMultiwordObject() && args.GetArgumentCount() > 0)
Jim Inghamebc09c32010-07-07 03:36:20 +0000704 {
705 if (argc >= 3)
706 {
707 const std::string sub_command = args.GetArgumentAtIndex(0);
708 assert (sub_command.length() != 0);
Greg Clayton998255b2012-10-13 02:07:45 +0000709 subcommand_obj_sp = cmd_obj->GetSubcommandSP (sub_command.c_str());
Jim Inghamebc09c32010-07-07 03:36:20 +0000710 if (subcommand_obj_sp.get())
711 {
712 sub_cmd_obj = subcommand_obj_sp.get();
713 use_subcommand = true;
714 args.Shift(); // Shift the sub_command word off the argument vector.
Caroline Tice844d2302010-12-09 22:52:49 +0000715 cmd_obj = sub_cmd_obj;
Jim Inghamebc09c32010-07-07 03:36:20 +0000716 }
717 else
718 {
Caroline Ticef415eeb2010-11-02 19:00:04 +0000719 result.AppendErrorWithFormat("'%s' is not a valid sub-command of '%s'. "
720 "Unable to create alias.\n",
721 sub_command.c_str(), actual_command.c_str());
Jim Inghamebc09c32010-07-07 03:36:20 +0000722 result.SetStatus (eReturnStatusFailed);
723 return false;
724 }
725 }
726 }
727
728 // Verify & handle any options/arguments passed to the alias command
729
730 if (args.GetArgumentCount () > 0)
731 {
Caroline Ticeca90c472011-05-06 21:37:15 +0000732 CommandObjectSP tmp_sp = m_interpreter.GetCommandSPExact (cmd_obj->GetCommandName(), false);
733 if (use_subcommand)
734 tmp_sp = m_interpreter.GetCommandSPExact (sub_cmd_obj->GetCommandName(), false);
735
736 std::string args_string;
737 args.GetCommandString (args_string);
738
739 if (!m_interpreter.ProcessAliasOptionsArgs (tmp_sp, args_string.c_str(), option_arg_vector_sp))
740 {
741 result.AppendError ("Unable to create requested alias.\n");
742 result.SetStatus (eReturnStatusFailed);
743 return false;
744 }
Jim Inghamebc09c32010-07-07 03:36:20 +0000745 }
746
747 // Create the alias.
748
Greg Claytona7015092010-09-18 01:14:36 +0000749 if (m_interpreter.AliasExists (alias_command.c_str())
750 || m_interpreter.UserCommandExists (alias_command.c_str()))
Jim Inghamebc09c32010-07-07 03:36:20 +0000751 {
Greg Claytona7015092010-09-18 01:14:36 +0000752 OptionArgVectorSP tmp_option_arg_sp (m_interpreter.GetAliasOptions (alias_command.c_str()));
Jim Inghamebc09c32010-07-07 03:36:20 +0000753 if (tmp_option_arg_sp.get())
754 {
755 if (option_arg_vector->size() == 0)
Greg Claytona7015092010-09-18 01:14:36 +0000756 m_interpreter.RemoveAliasOptions (alias_command.c_str());
Jim Inghamebc09c32010-07-07 03:36:20 +0000757 }
758 result.AppendWarningWithFormat ("Overwriting existing definition for '%s'.\n",
759 alias_command.c_str());
760 }
761
762 if (use_subcommand)
Greg Claytona7015092010-09-18 01:14:36 +0000763 m_interpreter.AddAlias (alias_command.c_str(), subcommand_obj_sp);
Jim Inghamebc09c32010-07-07 03:36:20 +0000764 else
Greg Claytona7015092010-09-18 01:14:36 +0000765 m_interpreter.AddAlias (alias_command.c_str(), command_obj_sp);
Jim Inghamebc09c32010-07-07 03:36:20 +0000766 if (option_arg_vector->size() > 0)
Greg Claytona7015092010-09-18 01:14:36 +0000767 m_interpreter.AddOrReplaceAliasOptions (alias_command.c_str(), option_arg_vector_sp);
Jim Inghamebc09c32010-07-07 03:36:20 +0000768 result.SetStatus (eReturnStatusSuccessFinishNoResult);
769 }
770 else
771 {
772 result.AppendErrorWithFormat ("'%s' is not an existing command.\n", actual_command.c_str());
773 result.SetStatus (eReturnStatusFailed);
Caroline Ticee7941792010-10-28 23:17:48 +0000774 return false;
Jim Inghamebc09c32010-07-07 03:36:20 +0000775 }
776 }
777
778 return result.Succeeded();
779 }
Jim Ingham5a988412012-06-08 21:56:10 +0000780
Jim Inghamebc09c32010-07-07 03:36:20 +0000781};
782
783#pragma mark CommandObjectCommandsUnalias
784//-------------------------------------------------------------------------
785// CommandObjectCommandsUnalias
786//-------------------------------------------------------------------------
787
Jim Ingham5a988412012-06-08 21:56:10 +0000788class CommandObjectCommandsUnalias : public CommandObjectParsed
Jim Inghamebc09c32010-07-07 03:36:20 +0000789{
790public:
Greg Claytona7015092010-09-18 01:14:36 +0000791 CommandObjectCommandsUnalias (CommandInterpreter &interpreter) :
Jim Ingham5a988412012-06-08 21:56:10 +0000792 CommandObjectParsed (interpreter,
Greg Clayton0e5e5a72011-04-20 22:55:21 +0000793 "command unalias",
Caroline Tice86ddae52010-09-12 04:56:10 +0000794 "Allow the user to remove/delete a user-defined command abbreviation.",
Caroline Tice405fe672010-10-04 22:28:36 +0000795 NULL)
Jim Inghamebc09c32010-07-07 03:36:20 +0000796 {
Caroline Tice405fe672010-10-04 22:28:36 +0000797 CommandArgumentEntry arg;
798 CommandArgumentData alias_arg;
799
800 // Define the first (and only) variant of this arg.
801 alias_arg.arg_type = eArgTypeAliasName;
802 alias_arg.arg_repetition = eArgRepeatPlain;
803
804 // There is only one variant this argument could be; put it into the argument entry.
805 arg.push_back (alias_arg);
806
807 // Push the data for the first argument into the m_arguments vector.
808 m_arguments.push_back (arg);
Jim Inghamebc09c32010-07-07 03:36:20 +0000809 }
810
811 ~CommandObjectCommandsUnalias()
812 {
813 }
814
Jim Ingham5a988412012-06-08 21:56:10 +0000815protected:
Jim Inghamebc09c32010-07-07 03:36:20 +0000816 bool
Jim Ingham5a988412012-06-08 21:56:10 +0000817 DoExecute (Args& args, CommandReturnObject &result)
Jim Inghamebc09c32010-07-07 03:36:20 +0000818 {
819 CommandObject::CommandMap::iterator pos;
820 CommandObject *cmd_obj;
821
822 if (args.GetArgumentCount() != 0)
823 {
824 const char *command_name = args.GetArgumentAtIndex(0);
Greg Claytona7015092010-09-18 01:14:36 +0000825 cmd_obj = m_interpreter.GetCommandObject(command_name);
Jim Inghamebc09c32010-07-07 03:36:20 +0000826 if (cmd_obj)
827 {
Greg Claytona7015092010-09-18 01:14:36 +0000828 if (m_interpreter.CommandExists (command_name))
Jim Inghamebc09c32010-07-07 03:36:20 +0000829 {
Greg Claytonb5472782015-01-09 19:08:20 +0000830 if (cmd_obj->IsRemovable())
831 {
832 result.AppendErrorWithFormat ("'%s' is not an alias, it is a debugger command which can be removed using the 'command delete' command.\n",
833 command_name);
834 }
835 else
836 {
837 result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be removed.\n",
838 command_name);
839 }
Jim Inghamebc09c32010-07-07 03:36:20 +0000840 result.SetStatus (eReturnStatusFailed);
841 }
842 else
843 {
844
Greg Claytona7015092010-09-18 01:14:36 +0000845 if (m_interpreter.RemoveAlias (command_name) == false)
Jim Inghamebc09c32010-07-07 03:36:20 +0000846 {
Greg Claytona7015092010-09-18 01:14:36 +0000847 if (m_interpreter.AliasExists (command_name))
Jim Inghamebc09c32010-07-07 03:36:20 +0000848 result.AppendErrorWithFormat ("Error occurred while attempting to unalias '%s'.\n",
849 command_name);
850 else
851 result.AppendErrorWithFormat ("'%s' is not an existing alias.\n", command_name);
852 result.SetStatus (eReturnStatusFailed);
853 }
854 else
855 result.SetStatus (eReturnStatusSuccessFinishNoResult);
856 }
857 }
858 else
859 {
860 result.AppendErrorWithFormat ("'%s' is not a known command.\nTry 'help' to see a "
861 "current list of commands.\n",
862 command_name);
863 result.SetStatus (eReturnStatusFailed);
864 }
865 }
866 else
867 {
868 result.AppendError ("must call 'unalias' with a valid alias");
869 result.SetStatus (eReturnStatusFailed);
870 }
871
872 return result.Succeeded();
873 }
874};
875
Greg Claytonb5472782015-01-09 19:08:20 +0000876#pragma mark CommandObjectCommandsDelete
877//-------------------------------------------------------------------------
878// CommandObjectCommandsDelete
879//-------------------------------------------------------------------------
880
881class CommandObjectCommandsDelete : public CommandObjectParsed
882{
883public:
884 CommandObjectCommandsDelete (CommandInterpreter &interpreter) :
885 CommandObjectParsed (interpreter,
886 "command delete",
887 "Allow the user to delete user-defined regular expression, python or multi-word commands.",
888 NULL)
889 {
890 CommandArgumentEntry arg;
891 CommandArgumentData alias_arg;
892
893 // Define the first (and only) variant of this arg.
894 alias_arg.arg_type = eArgTypeCommandName;
895 alias_arg.arg_repetition = eArgRepeatPlain;
896
897 // There is only one variant this argument could be; put it into the argument entry.
898 arg.push_back (alias_arg);
899
900 // Push the data for the first argument into the m_arguments vector.
901 m_arguments.push_back (arg);
902 }
903
904 ~CommandObjectCommandsDelete()
905 {
906 }
907
908protected:
909 bool
910 DoExecute (Args& args, CommandReturnObject &result)
911 {
912 CommandObject::CommandMap::iterator pos;
913
914 if (args.GetArgumentCount() != 0)
915 {
916 const char *command_name = args.GetArgumentAtIndex(0);
917 if (m_interpreter.CommandExists (command_name))
918 {
919 if (m_interpreter.RemoveCommand (command_name))
920 {
921 result.SetStatus (eReturnStatusSuccessFinishNoResult);
922 }
923 else
924 {
925 result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be removed.\n",
926 command_name);
927 result.SetStatus (eReturnStatusFailed);
928 }
929 }
930 else
931 {
932 result.AppendErrorWithFormat ("'%s' is not a known command.\nTry 'help' to see a current list of commands.\n",
933 command_name);
934 result.SetStatus (eReturnStatusFailed);
935 }
936 }
937 else
938 {
939 result.AppendErrorWithFormat ("must call '%s' with one or more valid user defined regular expression, python or multi-word command names", GetCommandName ());
940 result.SetStatus (eReturnStatusFailed);
941 }
942
943 return result.Succeeded();
944 }
945};
946
Greg Claytonde164aa2011-04-20 16:37:46 +0000947//-------------------------------------------------------------------------
948// CommandObjectCommandsAddRegex
949//-------------------------------------------------------------------------
Jim Ingham5a988412012-06-08 21:56:10 +0000950#pragma mark CommandObjectCommandsAddRegex
Greg Claytonde164aa2011-04-20 16:37:46 +0000951
Greg Clayton44d93782014-01-27 23:43:24 +0000952class CommandObjectCommandsAddRegex :
953 public CommandObjectParsed,
Greg Claytonea508632014-11-18 00:43:17 +0000954 public IOHandlerDelegateMultiline
Greg Claytonde164aa2011-04-20 16:37:46 +0000955{
956public:
957 CommandObjectCommandsAddRegex (CommandInterpreter &interpreter) :
Jim Ingham5a988412012-06-08 21:56:10 +0000958 CommandObjectParsed (interpreter,
Greg Clayton0e5e5a72011-04-20 22:55:21 +0000959 "command regex",
Greg Claytonde164aa2011-04-20 16:37:46 +0000960 "Allow the user to create a regular expression command.",
Greg Clayton0e5e5a72011-04-20 22:55:21 +0000961 "command regex <cmd-name> [s/<regex>/<subst>/ ...]"),
Greg Claytonea508632014-11-18 00:43:17 +0000962 IOHandlerDelegateMultiline ("", IOHandlerDelegate::Completion::LLDBCommand),
Greg Claytonde164aa2011-04-20 16:37:46 +0000963 m_options (interpreter)
964 {
Greg Clayton0e5e5a72011-04-20 22:55:21 +0000965 SetHelpLong(
966"This command allows the user to create powerful regular expression commands\n"
967"with substitutions. The regular expressions and substitutions are specified\n"
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +0000968"using the regular expression substitution format of:\n"
Greg Clayton0e5e5a72011-04-20 22:55:21 +0000969"\n"
970" s/<regex>/<subst>/\n"
971"\n"
972"<regex> is a regular expression that can use parenthesis to capture regular\n"
973"expression input and substitute the captured matches in the output using %1\n"
974"for the first match, %2 for the second, and so on.\n"
975"\n"
976"The regular expressions can all be specified on the command line if more than\n"
977"one argument is provided. If just the command name is provided on the command\n"
978"line, then the regular expressions and substitutions can be entered on separate\n"
979" lines, followed by an empty line to terminate the command definition.\n"
980"\n"
981"EXAMPLES\n"
982"\n"
Sean Callananadc43c92012-08-16 21:46:58 +0000983"The following example will define a regular expression command named 'f' that\n"
Greg Clayton0e5e5a72011-04-20 22:55:21 +0000984"will call 'finish' if there are no arguments, or 'frame select <frame-idx>' if\n"
985"a number follows 'f':\n"
Sean Callananadc43c92012-08-16 21:46:58 +0000986"\n"
987" (lldb) command regex f s/^$/finish/ 's/([0-9]+)/frame select %1/'\n"
988"\n"
Greg Clayton0e5e5a72011-04-20 22:55:21 +0000989 );
Greg Claytonde164aa2011-04-20 16:37:46 +0000990 }
991
992 ~CommandObjectCommandsAddRegex()
993 {
994 }
995
996
Jim Ingham5a988412012-06-08 21:56:10 +0000997protected:
Greg Clayton44d93782014-01-27 23:43:24 +0000998
Greg Claytonea508632014-11-18 00:43:17 +0000999 void
1000 IOHandlerActivated (IOHandler &io_handler) override
Greg Clayton44d93782014-01-27 23:43:24 +00001001 {
1002 StreamFileSP output_sp(io_handler.GetOutputStreamFile());
1003 if (output_sp)
1004 {
1005 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");
1006 output_sp->Flush();
1007 }
1008 }
1009
Greg Claytonea508632014-11-18 00:43:17 +00001010 void
1011 IOHandlerInputComplete (IOHandler &io_handler, std::string &data) override
Greg Clayton44d93782014-01-27 23:43:24 +00001012 {
1013 io_handler.SetIsDone(true);
1014 if (m_regex_cmd_ap.get())
1015 {
1016 StringList lines;
1017 if (lines.SplitIntoLines (data))
1018 {
1019 const size_t num_lines = lines.GetSize();
1020 bool check_only = false;
1021 for (size_t i=0; i<num_lines; ++i)
1022 {
Greg Clayton44d93782014-01-27 23:43:24 +00001023 llvm::StringRef bytes_strref (lines[i]);
1024 Error error = AppendRegexSubstitution (bytes_strref, check_only);
1025 if (error.Fail())
1026 {
1027 if (!m_interpreter.GetDebugger().GetCommandInterpreter().GetBatchCommandMode())
1028 {
1029 StreamSP out_stream = m_interpreter.GetDebugger().GetAsyncOutputStream();
1030 out_stream->Printf("error: %s\n", error.AsCString());
1031 }
1032 }
1033 }
1034 }
1035 if (m_regex_cmd_ap->HasRegexEntries())
1036 {
1037 CommandObjectSP cmd_sp (m_regex_cmd_ap.release());
1038 m_interpreter.AddCommand(cmd_sp->GetCommandName(), cmd_sp, true);
1039 }
1040 }
1041 }
Greg Clayton44d93782014-01-27 23:43:24 +00001042
Greg Claytonde164aa2011-04-20 16:37:46 +00001043 bool
Eric Christopherb0a18142014-11-18 22:40:27 +00001044 DoExecute (Args& command, CommandReturnObject &result) override
Greg Claytonde164aa2011-04-20 16:37:46 +00001045 {
Jim Ingham5a988412012-06-08 21:56:10 +00001046 const size_t argc = command.GetArgumentCount();
Greg Clayton0e5e5a72011-04-20 22:55:21 +00001047 if (argc == 0)
Greg Claytonde164aa2011-04-20 16:37:46 +00001048 {
Jason Molenda69c12cc2011-11-10 22:43:35 +00001049 result.AppendError ("usage: 'command regex <command-name> [s/<regex1>/<subst1>/ s/<regex2>/<subst2>/ ...]'\n");
Greg Clayton0e5e5a72011-04-20 22:55:21 +00001050 result.SetStatus (eReturnStatusFailed);
1051 }
1052 else
1053 {
1054 Error error;
Jim Ingham5a988412012-06-08 21:56:10 +00001055 const char *name = command.GetArgumentAtIndex(0);
Greg Claytonde164aa2011-04-20 16:37:46 +00001056 m_regex_cmd_ap.reset (new CommandObjectRegexCommand (m_interpreter,
1057 name,
1058 m_options.GetHelp (),
1059 m_options.GetSyntax (),
Greg Claytonb5472782015-01-09 19:08:20 +00001060 10,
1061 0,
1062 true));
Greg Clayton0e5e5a72011-04-20 22:55:21 +00001063
1064 if (argc == 1)
Greg Claytonde164aa2011-04-20 16:37:46 +00001065 {
Greg Clayton44d93782014-01-27 23:43:24 +00001066 Debugger &debugger = m_interpreter.GetDebugger();
Kate Stonee30f11d2014-11-17 19:06:59 +00001067 bool color_prompt = debugger.GetUseColor();
Greg Clayton44d93782014-01-27 23:43:24 +00001068 const bool multiple_lines = true; // Get multiple lines
1069 IOHandlerSP io_handler_sp (new IOHandlerEditline (debugger,
Kate Stonee30f11d2014-11-17 19:06:59 +00001070 IOHandler::Type::Other,
Greg Clayton73d80fa2014-07-09 20:18:54 +00001071 "lldb-regex", // Name of input reader for history
Greg Claytonea508632014-11-18 00:43:17 +00001072 "> ", // Prompt
Kate Stonee30f11d2014-11-17 19:06:59 +00001073 NULL, // Continuation prompt
Greg Clayton44d93782014-01-27 23:43:24 +00001074 multiple_lines,
Kate Stonee30f11d2014-11-17 19:06:59 +00001075 color_prompt,
Greg Claytonf6913cd2014-03-07 00:53:24 +00001076 0, // Don't show line numbers
Greg Clayton44d93782014-01-27 23:43:24 +00001077 *this));
1078
1079 if (io_handler_sp)
Greg Clayton0e5e5a72011-04-20 22:55:21 +00001080 {
Greg Clayton44d93782014-01-27 23:43:24 +00001081 debugger.PushIOHandler(io_handler_sp);
1082 result.SetStatus (eReturnStatusSuccessFinishNoResult);
Greg Claytonde164aa2011-04-20 16:37:46 +00001083 }
1084 }
Greg Clayton0e5e5a72011-04-20 22:55:21 +00001085 else
1086 {
1087 for (size_t arg_idx = 1; arg_idx < argc; ++arg_idx)
1088 {
Jim Ingham5a988412012-06-08 21:56:10 +00001089 llvm::StringRef arg_strref (command.GetArgumentAtIndex(arg_idx));
Greg Clayton44d93782014-01-27 23:43:24 +00001090 bool check_only = false;
1091 error = AppendRegexSubstitution (arg_strref, check_only);
Greg Clayton0e5e5a72011-04-20 22:55:21 +00001092 if (error.Fail())
1093 break;
1094 }
1095
1096 if (error.Success())
1097 {
1098 AddRegexCommandToInterpreter();
1099 }
1100 }
1101 if (error.Fail())
1102 {
1103 result.AppendError (error.AsCString());
1104 result.SetStatus (eReturnStatusFailed);
1105 }
Greg Claytonde164aa2011-04-20 16:37:46 +00001106 }
Greg Clayton0e5e5a72011-04-20 22:55:21 +00001107
Greg Claytonde164aa2011-04-20 16:37:46 +00001108 return result.Succeeded();
1109 }
1110
Greg Clayton0e5e5a72011-04-20 22:55:21 +00001111 Error
Greg Clayton44d93782014-01-27 23:43:24 +00001112 AppendRegexSubstitution (const llvm::StringRef &regex_sed, bool check_only)
Greg Claytonde164aa2011-04-20 16:37:46 +00001113 {
Greg Clayton0e5e5a72011-04-20 22:55:21 +00001114 Error error;
1115
1116 if (m_regex_cmd_ap.get() == NULL)
Greg Claytonde164aa2011-04-20 16:37:46 +00001117 {
Greg Clayton0e5e5a72011-04-20 22:55:21 +00001118 error.SetErrorStringWithFormat("invalid regular expression command object for: '%.*s'",
1119 (int)regex_sed.size(),
1120 regex_sed.data());
1121 return error;
Greg Claytonde164aa2011-04-20 16:37:46 +00001122 }
Greg Clayton0e5e5a72011-04-20 22:55:21 +00001123
1124 size_t regex_sed_size = regex_sed.size();
1125
1126 if (regex_sed_size <= 1)
1127 {
1128 error.SetErrorStringWithFormat("regular expression substitution string is too short: '%.*s'",
1129 (int)regex_sed.size(),
1130 regex_sed.data());
1131 return error;
1132 }
1133
1134 if (regex_sed[0] != 's')
1135 {
1136 error.SetErrorStringWithFormat("regular expression substitution string doesn't start with 's': '%.*s'",
1137 (int)regex_sed.size(),
1138 regex_sed.data());
1139 return error;
1140 }
1141 const size_t first_separator_char_pos = 1;
1142 // use the char that follows 's' as the regex separator character
1143 // so we can have "s/<regex>/<subst>/" or "s|<regex>|<subst>|"
1144 const char separator_char = regex_sed[first_separator_char_pos];
1145 const size_t second_separator_char_pos = regex_sed.find (separator_char, first_separator_char_pos + 1);
1146
1147 if (second_separator_char_pos == std::string::npos)
1148 {
Greg Claytonea508632014-11-18 00:43:17 +00001149 error.SetErrorStringWithFormat("missing second '%c' separator char after '%.*s' in '%.*s'",
Greg Clayton0e5e5a72011-04-20 22:55:21 +00001150 separator_char,
1151 (int)(regex_sed.size() - first_separator_char_pos - 1),
Greg Claytonea508632014-11-18 00:43:17 +00001152 regex_sed.data() + (first_separator_char_pos + 1),
1153 (int)regex_sed.size(),
1154 regex_sed.data());
1155 return error;
Greg Clayton0e5e5a72011-04-20 22:55:21 +00001156 }
1157
1158 const size_t third_separator_char_pos = regex_sed.find (separator_char, second_separator_char_pos + 1);
1159
1160 if (third_separator_char_pos == std::string::npos)
1161 {
Greg Claytonea508632014-11-18 00:43:17 +00001162 error.SetErrorStringWithFormat("missing third '%c' separator char after '%.*s' in '%.*s'",
Greg Clayton0e5e5a72011-04-20 22:55:21 +00001163 separator_char,
1164 (int)(regex_sed.size() - second_separator_char_pos - 1),
Greg Claytonea508632014-11-18 00:43:17 +00001165 regex_sed.data() + (second_separator_char_pos + 1),
1166 (int)regex_sed.size(),
1167 regex_sed.data());
Greg Clayton0e5e5a72011-04-20 22:55:21 +00001168 return error;
1169 }
1170
1171 if (third_separator_char_pos != regex_sed_size - 1)
1172 {
1173 // Make sure that everything that follows the last regex
1174 // separator char
1175 if (regex_sed.find_first_not_of("\t\n\v\f\r ", third_separator_char_pos + 1) != std::string::npos)
1176 {
1177 error.SetErrorStringWithFormat("extra data found after the '%.*s' regular expression substitution string: '%.*s'",
1178 (int)third_separator_char_pos + 1,
1179 regex_sed.data(),
1180 (int)(regex_sed.size() - third_separator_char_pos - 1),
1181 regex_sed.data() + (third_separator_char_pos + 1));
1182 return error;
1183 }
1184
1185 }
1186 else if (first_separator_char_pos + 1 == second_separator_char_pos)
1187 {
1188 error.SetErrorStringWithFormat("<regex> can't be empty in 's%c<regex>%c<subst>%c' string: '%.*s'",
1189 separator_char,
1190 separator_char,
1191 separator_char,
1192 (int)regex_sed.size(),
1193 regex_sed.data());
1194 return error;
1195 }
1196 else if (second_separator_char_pos + 1 == third_separator_char_pos)
1197 {
1198 error.SetErrorStringWithFormat("<subst> can't be empty in 's%c<regex>%c<subst>%c' string: '%.*s'",
1199 separator_char,
1200 separator_char,
1201 separator_char,
1202 (int)regex_sed.size(),
1203 regex_sed.data());
1204 return error;
1205 }
Greg Clayton44d93782014-01-27 23:43:24 +00001206
1207 if (check_only == false)
1208 {
1209 std::string regex(regex_sed.substr(first_separator_char_pos + 1, second_separator_char_pos - first_separator_char_pos - 1));
1210 std::string subst(regex_sed.substr(second_separator_char_pos + 1, third_separator_char_pos - second_separator_char_pos - 1));
1211 m_regex_cmd_ap->AddRegexCommand (regex.c_str(),
1212 subst.c_str());
1213 }
Greg Clayton0e5e5a72011-04-20 22:55:21 +00001214 return error;
Greg Claytonde164aa2011-04-20 16:37:46 +00001215 }
1216
1217 void
Greg Clayton0e5e5a72011-04-20 22:55:21 +00001218 AddRegexCommandToInterpreter()
Greg Claytonde164aa2011-04-20 16:37:46 +00001219 {
1220 if (m_regex_cmd_ap.get())
1221 {
1222 if (m_regex_cmd_ap->HasRegexEntries())
1223 {
1224 CommandObjectSP cmd_sp (m_regex_cmd_ap.release());
1225 m_interpreter.AddCommand(cmd_sp->GetCommandName(), cmd_sp, true);
1226 }
1227 }
1228 }
1229
Greg Claytonde164aa2011-04-20 16:37:46 +00001230private:
Greg Clayton7b0992d2013-04-18 22:45:39 +00001231 std::unique_ptr<CommandObjectRegexCommand> m_regex_cmd_ap;
Greg Claytonde164aa2011-04-20 16:37:46 +00001232
1233 class CommandOptions : public Options
1234 {
1235 public:
1236
1237 CommandOptions (CommandInterpreter &interpreter) :
1238 Options (interpreter)
1239 {
1240 }
1241
1242 virtual
1243 ~CommandOptions (){}
1244
1245 virtual Error
1246 SetOptionValue (uint32_t option_idx, const char *option_arg)
1247 {
1248 Error error;
Greg Clayton3bcdfc02012-12-04 00:32:51 +00001249 const int short_option = m_getopt_table[option_idx].val;
Greg Claytonde164aa2011-04-20 16:37:46 +00001250
1251 switch (short_option)
1252 {
1253 case 'h':
1254 m_help.assign (option_arg);
1255 break;
1256 case 's':
1257 m_syntax.assign (option_arg);
1258 break;
1259
1260 default:
Greg Clayton86edbf42011-10-26 00:56:27 +00001261 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
Greg Claytonde164aa2011-04-20 16:37:46 +00001262 break;
1263 }
1264
1265 return error;
1266 }
1267
1268 void
1269 OptionParsingStarting ()
1270 {
1271 m_help.clear();
1272 m_syntax.clear();
1273 }
1274
1275 const OptionDefinition*
1276 GetDefinitions ()
1277 {
1278 return g_option_table;
1279 }
1280
1281 // Options table: Required for subclasses of Options.
1282
1283 static OptionDefinition g_option_table[];
1284
1285 const char *
1286 GetHelp ()
1287 {
1288 if (m_help.empty())
1289 return NULL;
1290 return m_help.c_str();
1291 }
1292 const char *
1293 GetSyntax ()
1294 {
1295 if (m_syntax.empty())
1296 return NULL;
1297 return m_syntax.c_str();
1298 }
1299 // Instance variables to hold the values for command options.
1300 protected:
1301 std::string m_help;
1302 std::string m_syntax;
1303 };
Jim Ingham5a988412012-06-08 21:56:10 +00001304
Eric Christopherb0a18142014-11-18 22:40:27 +00001305 Options *
1306 GetOptions () override
Greg Claytonde164aa2011-04-20 16:37:46 +00001307 {
1308 return &m_options;
1309 }
Jim Ingham5a988412012-06-08 21:56:10 +00001310
1311 CommandOptions m_options;
Greg Claytonde164aa2011-04-20 16:37:46 +00001312};
1313
Greg Claytonde164aa2011-04-20 16:37:46 +00001314OptionDefinition
1315CommandObjectCommandsAddRegex::CommandOptions::g_option_table[] =
1316{
Zachary Turnerd37221d2014-07-09 16:31:49 +00001317{ LLDB_OPT_SET_1, false, "help" , 'h', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeNone, "The help text to display for this command."},
1318{ LLDB_OPT_SET_1, false, "syntax", 's', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeNone, "A syntax string showing the typical usage syntax."},
1319{ 0 , false, NULL , 0 , 0 , NULL, NULL, 0, eArgTypeNone, NULL }
Greg Claytonde164aa2011-04-20 16:37:46 +00001320};
1321
1322
Jim Ingham5a988412012-06-08 21:56:10 +00001323class CommandObjectPythonFunction : public CommandObjectRaw
Enrico Granata223383e2011-08-16 23:24:13 +00001324{
1325private:
1326 std::string m_function_name;
Enrico Granata0a305db2011-11-07 22:57:04 +00001327 ScriptedCommandSynchronicity m_synchro;
Enrico Granatafac939e2012-09-18 21:53:02 +00001328 bool m_fetched_help_long;
Enrico Granata223383e2011-08-16 23:24:13 +00001329
1330public:
1331
1332 CommandObjectPythonFunction (CommandInterpreter &interpreter,
1333 std::string name,
Enrico Granata0a305db2011-11-07 22:57:04 +00001334 std::string funct,
Enrico Granata735152e2014-09-15 17:52:44 +00001335 std::string help,
Enrico Granata0a305db2011-11-07 22:57:04 +00001336 ScriptedCommandSynchronicity synch) :
Jim Ingham5a988412012-06-08 21:56:10 +00001337 CommandObjectRaw (interpreter,
1338 name.c_str(),
Enrico Granata735152e2014-09-15 17:52:44 +00001339 NULL,
Jim Ingham5a988412012-06-08 21:56:10 +00001340 NULL),
1341 m_function_name(funct),
Enrico Granatafac939e2012-09-18 21:53:02 +00001342 m_synchro(synch),
1343 m_fetched_help_long(false)
Enrico Granata223383e2011-08-16 23:24:13 +00001344 {
Enrico Granata735152e2014-09-15 17:52:44 +00001345 if (!help.empty())
1346 SetHelp(help.c_str());
1347 else
1348 {
1349 StreamString stream;
1350 stream.Printf("For more information run 'help %s'",name.c_str());
1351 SetHelp(stream.GetData());
1352 }
Enrico Granata223383e2011-08-16 23:24:13 +00001353 }
1354
1355 virtual
1356 ~CommandObjectPythonFunction ()
1357 {
1358 }
1359
1360 virtual bool
Greg Clayton3a18e312012-10-08 22:41:53 +00001361 IsRemovable () const
Jim Ingham5a988412012-06-08 21:56:10 +00001362 {
1363 return true;
1364 }
1365
1366 const std::string&
1367 GetFunctionName ()
1368 {
1369 return m_function_name;
1370 }
1371
1372 ScriptedCommandSynchronicity
1373 GetSynchronicity ()
1374 {
1375 return m_synchro;
1376 }
1377
Enrico Granatafac939e2012-09-18 21:53:02 +00001378 virtual const char *
1379 GetHelpLong ()
1380 {
1381 if (!m_fetched_help_long)
1382 {
1383 ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter();
1384 if (scripter)
1385 {
1386 std::string docstring;
1387 m_fetched_help_long = scripter->GetDocumentationForItem(m_function_name.c_str(),docstring);
1388 if (!docstring.empty())
1389 SetHelpLong(docstring);
1390 }
1391 }
1392 return CommandObjectRaw::GetHelpLong();
1393 }
1394
Jim Ingham5a988412012-06-08 21:56:10 +00001395protected:
1396 virtual bool
1397 DoExecute (const char *raw_command_line, CommandReturnObject &result)
Enrico Granata223383e2011-08-16 23:24:13 +00001398 {
1399 ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter();
1400
1401 Error error;
1402
Jim Ingham70f11f82012-06-27 17:25:36 +00001403 result.SetStatus(eReturnStatusInvalid);
1404
Enrico Granata223383e2011-08-16 23:24:13 +00001405 if (!scripter || scripter->RunScriptBasedCommand(m_function_name.c_str(),
1406 raw_command_line,
Enrico Granata0a305db2011-11-07 22:57:04 +00001407 m_synchro,
Enrico Granata223383e2011-08-16 23:24:13 +00001408 result,
Enrico Granata06be0592014-10-01 21:47:29 +00001409 error,
1410 m_exe_ctx) == false)
Enrico Granata223383e2011-08-16 23:24:13 +00001411 {
1412 result.AppendError(error.AsCString());
1413 result.SetStatus(eReturnStatusFailed);
1414 }
1415 else
Jim Ingham70f11f82012-06-27 17:25:36 +00001416 {
1417 // Don't change the status if the command already set it...
1418 if (result.GetStatus() == eReturnStatusInvalid)
1419 {
Daniel Malea9a71a7d2013-07-03 17:58:31 +00001420 if (result.GetOutputData() == NULL || result.GetOutputData()[0] == '\0')
Jim Ingham70f11f82012-06-27 17:25:36 +00001421 result.SetStatus(eReturnStatusSuccessFinishNoResult);
1422 else
1423 result.SetStatus(eReturnStatusSuccessFinishResult);
1424 }
1425 }
Enrico Granata223383e2011-08-16 23:24:13 +00001426
1427 return result.Succeeded();
1428 }
1429
Enrico Granata223383e2011-08-16 23:24:13 +00001430};
1431
Enrico Granata9fe00e52015-03-13 02:20:41 +00001432class CommandObjectScriptingObject : public CommandObjectRaw
1433{
1434private:
Zachary Turner0641ca12015-03-17 20:04:04 +00001435 StructuredData::GenericSP m_cmd_obj_sp;
Enrico Granata9fe00e52015-03-13 02:20:41 +00001436 ScriptedCommandSynchronicity m_synchro;
Enrico Granata6f79bb22015-03-13 22:22:28 +00001437 bool m_fetched_help_short:1;
1438 bool m_fetched_help_long:1;
Enrico Granata9fe00e52015-03-13 02:20:41 +00001439
1440public:
1441
1442 CommandObjectScriptingObject (CommandInterpreter &interpreter,
1443 std::string name,
Zachary Turner0641ca12015-03-17 20:04:04 +00001444 StructuredData::GenericSP cmd_obj_sp,
Enrico Granata9fe00e52015-03-13 02:20:41 +00001445 ScriptedCommandSynchronicity synch) :
1446 CommandObjectRaw (interpreter,
1447 name.c_str(),
1448 NULL,
1449 NULL),
1450 m_cmd_obj_sp(cmd_obj_sp),
Enrico Granata6f79bb22015-03-13 22:22:28 +00001451 m_synchro(synch),
1452 m_fetched_help_short(false),
1453 m_fetched_help_long(false)
Enrico Granata9fe00e52015-03-13 02:20:41 +00001454 {
1455 StreamString stream;
1456 stream.Printf("For more information run 'help %s'",name.c_str());
1457 SetHelp(stream.GetData());
Enrico Granatae87764f2015-05-27 05:04:35 +00001458 if (ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter())
1459 GetFlags().Set(scripter->GetFlagsForCommandObject(cmd_obj_sp));
Enrico Granata9fe00e52015-03-13 02:20:41 +00001460 }
1461
1462 virtual
1463 ~CommandObjectScriptingObject ()
1464 {
1465 }
1466
1467 virtual bool
1468 IsRemovable () const
1469 {
1470 return true;
1471 }
1472
Zachary Turner0641ca12015-03-17 20:04:04 +00001473 StructuredData::GenericSP
Enrico Granata9fe00e52015-03-13 02:20:41 +00001474 GetImplementingObject ()
1475 {
1476 return m_cmd_obj_sp;
1477 }
1478
1479 ScriptedCommandSynchronicity
1480 GetSynchronicity ()
1481 {
1482 return m_synchro;
1483 }
Enrico Granata6f79bb22015-03-13 22:22:28 +00001484
1485 virtual const char *
1486 GetHelp ()
1487 {
1488 if (!m_fetched_help_short)
1489 {
1490 ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter();
1491 if (scripter)
1492 {
1493 std::string docstring;
1494 m_fetched_help_short = scripter->GetShortHelpForCommandObject(m_cmd_obj_sp,docstring);
1495 if (!docstring.empty())
1496 SetHelp(docstring);
1497 }
1498 }
1499 return CommandObjectRaw::GetHelp();
1500 }
Enrico Granata9fe00e52015-03-13 02:20:41 +00001501
1502 virtual const char *
1503 GetHelpLong ()
1504 {
Enrico Granata6f79bb22015-03-13 22:22:28 +00001505 if (!m_fetched_help_long)
1506 {
1507 ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter();
1508 if (scripter)
1509 {
1510 std::string docstring;
1511 m_fetched_help_long = scripter->GetLongHelpForCommandObject(m_cmd_obj_sp,docstring);
1512 if (!docstring.empty())
1513 SetHelpLong(docstring);
1514 }
1515 }
Enrico Granata9fe00e52015-03-13 02:20:41 +00001516 return CommandObjectRaw::GetHelpLong();
1517 }
1518
1519protected:
1520 virtual bool
1521 DoExecute (const char *raw_command_line, CommandReturnObject &result)
1522 {
1523 ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter();
1524
1525 Error error;
1526
1527 result.SetStatus(eReturnStatusInvalid);
1528
1529 if (!scripter || scripter->RunScriptBasedCommand(m_cmd_obj_sp,
1530 raw_command_line,
1531 m_synchro,
1532 result,
1533 error,
1534 m_exe_ctx) == false)
1535 {
1536 result.AppendError(error.AsCString());
1537 result.SetStatus(eReturnStatusFailed);
1538 }
1539 else
1540 {
1541 // Don't change the status if the command already set it...
1542 if (result.GetStatus() == eReturnStatusInvalid)
1543 {
1544 if (result.GetOutputData() == NULL || result.GetOutputData()[0] == '\0')
1545 result.SetStatus(eReturnStatusSuccessFinishNoResult);
1546 else
1547 result.SetStatus(eReturnStatusSuccessFinishResult);
1548 }
1549 }
1550
1551 return result.Succeeded();
1552 }
1553
1554};
1555
Enrico Granataa9dbf432011-10-17 21:45:27 +00001556//-------------------------------------------------------------------------
1557// CommandObjectCommandsScriptImport
1558//-------------------------------------------------------------------------
1559
Jim Ingham5a988412012-06-08 21:56:10 +00001560class CommandObjectCommandsScriptImport : public CommandObjectParsed
Enrico Granataa9dbf432011-10-17 21:45:27 +00001561{
Jim Ingham5a988412012-06-08 21:56:10 +00001562public:
1563 CommandObjectCommandsScriptImport (CommandInterpreter &interpreter) :
1564 CommandObjectParsed (interpreter,
1565 "command script import",
1566 "Import a scripting module in LLDB.",
1567 NULL),
1568 m_options(interpreter)
1569 {
1570 CommandArgumentEntry arg1;
1571 CommandArgumentData cmd_arg;
1572
1573 // Define the first (and only) variant of this arg.
1574 cmd_arg.arg_type = eArgTypeFilename;
1575 cmd_arg.arg_repetition = eArgRepeatPlain;
1576
1577 // There is only one variant this argument could be; put it into the argument entry.
1578 arg1.push_back (cmd_arg);
1579
1580 // Push the data for the first argument into the m_arguments vector.
1581 m_arguments.push_back (arg1);
1582 }
1583
1584 ~CommandObjectCommandsScriptImport ()
1585 {
1586 }
1587
Greg Claytonc7bece562013-01-25 18:06:21 +00001588 virtual int
Jim Ingham5a988412012-06-08 21:56:10 +00001589 HandleArgumentCompletion (Args &input,
1590 int &cursor_index,
1591 int &cursor_char_position,
1592 OptionElementVector &opt_element_vector,
1593 int match_start_point,
1594 int max_return_elements,
1595 bool &word_complete,
1596 StringList &matches)
1597 {
1598 std::string completion_str (input.GetArgumentAtIndex(cursor_index));
1599 completion_str.erase (cursor_char_position);
1600
1601 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
1602 CommandCompletions::eDiskFileCompletion,
1603 completion_str.c_str(),
1604 match_start_point,
1605 max_return_elements,
1606 NULL,
1607 word_complete,
1608 matches);
1609 return matches.GetSize();
1610 }
1611
1612 virtual Options *
1613 GetOptions ()
1614 {
1615 return &m_options;
1616 }
1617
1618protected:
Enrico Granata0a305db2011-11-07 22:57:04 +00001619
1620 class CommandOptions : public Options
1621 {
1622 public:
1623
1624 CommandOptions (CommandInterpreter &interpreter) :
Jim Ingham5a988412012-06-08 21:56:10 +00001625 Options (interpreter)
Enrico Granata0a305db2011-11-07 22:57:04 +00001626 {
1627 }
1628
1629 virtual
1630 ~CommandOptions (){}
1631
1632 virtual Error
1633 SetOptionValue (uint32_t option_idx, const char *option_arg)
1634 {
1635 Error error;
Greg Clayton3bcdfc02012-12-04 00:32:51 +00001636 const int short_option = m_getopt_table[option_idx].val;
Enrico Granata0a305db2011-11-07 22:57:04 +00001637
1638 switch (short_option)
1639 {
1640 case 'r':
1641 m_allow_reload = true;
1642 break;
1643 default:
1644 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1645 break;
1646 }
1647
1648 return error;
1649 }
1650
1651 void
1652 OptionParsingStarting ()
1653 {
Enrico Granatae0c70f12013-05-31 01:03:09 +00001654 m_allow_reload = true;
Enrico Granata0a305db2011-11-07 22:57:04 +00001655 }
1656
1657 const OptionDefinition*
1658 GetDefinitions ()
1659 {
1660 return g_option_table;
1661 }
1662
1663 // Options table: Required for subclasses of Options.
1664
1665 static OptionDefinition g_option_table[];
1666
1667 // Instance variables to hold the values for command options.
1668
1669 bool m_allow_reload;
1670 };
Enrico Granata0a305db2011-11-07 22:57:04 +00001671
Enrico Granataa9dbf432011-10-17 21:45:27 +00001672 bool
Jim Ingham5a988412012-06-08 21:56:10 +00001673 DoExecute (Args& command, CommandReturnObject &result)
Enrico Granataa9dbf432011-10-17 21:45:27 +00001674 {
1675
1676 if (m_interpreter.GetDebugger().GetScriptLanguage() != lldb::eScriptLanguagePython)
1677 {
1678 result.AppendError ("only scripting language supported for module importing is currently Python");
1679 result.SetStatus (eReturnStatusFailed);
1680 return false;
1681 }
1682
Jim Ingham5a988412012-06-08 21:56:10 +00001683 size_t argc = command.GetArgumentCount();
Enrico Granataa9dbf432011-10-17 21:45:27 +00001684
1685 if (argc != 1)
1686 {
1687 result.AppendError ("'command script import' requires one argument");
1688 result.SetStatus (eReturnStatusFailed);
1689 return false;
1690 }
1691
Jim Ingham5a988412012-06-08 21:56:10 +00001692 std::string path = command.GetArgumentAtIndex(0);
Enrico Granataa9dbf432011-10-17 21:45:27 +00001693 Error error;
1694
Greg Claytonc9d645d2012-10-18 22:40:37 +00001695 const bool init_session = true;
Enrico Granata078551c2013-05-09 19:33:49 +00001696 // FIXME: this is necessary because CommandObject::CheckRequirements() assumes that
1697 // commands won't ever be recursively invoked, but it's actually possible to craft
1698 // a Python script that does other "command script imports" in __lldb_init_module
1699 // the real fix is to have recursive commands possible with a CommandInvocation object
1700 // separate from the CommandObject itself, so that recursive command invocations
1701 // won't stomp on each other (wrt to execution contents, options, and more)
1702 m_exe_ctx.Clear();
Enrico Granataa9dbf432011-10-17 21:45:27 +00001703 if (m_interpreter.GetScriptInterpreter()->LoadScriptingModule(path.c_str(),
Enrico Granata0a305db2011-11-07 22:57:04 +00001704 m_options.m_allow_reload,
Greg Claytonc9d645d2012-10-18 22:40:37 +00001705 init_session,
Enrico Granataa9dbf432011-10-17 21:45:27 +00001706 error))
1707 {
1708 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1709 }
1710 else
1711 {
1712 result.AppendErrorWithFormat("module importing failed: %s", error.AsCString());
1713 result.SetStatus (eReturnStatusFailed);
1714 }
1715
1716 return result.Succeeded();
1717 }
Enrico Granata0a305db2011-11-07 22:57:04 +00001718
Jim Ingham5a988412012-06-08 21:56:10 +00001719 CommandOptions m_options;
Enrico Granataa9dbf432011-10-17 21:45:27 +00001720};
Enrico Granata223383e2011-08-16 23:24:13 +00001721
Enrico Granata0a305db2011-11-07 22:57:04 +00001722OptionDefinition
1723CommandObjectCommandsScriptImport::CommandOptions::g_option_table[] =
1724{
Zachary Turnerd37221d2014-07-09 16:31:49 +00001725 { LLDB_OPT_SET_1, false, "allow-reload", 'r', OptionParser::eNoArgument, NULL, 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."},
1726 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
Enrico Granata0a305db2011-11-07 22:57:04 +00001727};
1728
1729
Enrico Granata223383e2011-08-16 23:24:13 +00001730//-------------------------------------------------------------------------
1731// CommandObjectCommandsScriptAdd
1732//-------------------------------------------------------------------------
1733
Greg Clayton44d93782014-01-27 23:43:24 +00001734class CommandObjectCommandsScriptAdd :
1735 public CommandObjectParsed,
1736 public IOHandlerDelegateMultiline
Enrico Granata223383e2011-08-16 23:24:13 +00001737{
Jim Ingham5a988412012-06-08 21:56:10 +00001738public:
1739 CommandObjectCommandsScriptAdd(CommandInterpreter &interpreter) :
1740 CommandObjectParsed (interpreter,
1741 "command script add",
1742 "Add a scripted function as an LLDB command.",
1743 NULL),
Greg Claytonc3d874a2014-05-08 16:59:00 +00001744 IOHandlerDelegateMultiline ("DONE"),
Jim Ingham5a988412012-06-08 21:56:10 +00001745 m_options (interpreter)
1746 {
1747 CommandArgumentEntry arg1;
1748 CommandArgumentData cmd_arg;
1749
1750 // Define the first (and only) variant of this arg.
1751 cmd_arg.arg_type = eArgTypeCommandName;
1752 cmd_arg.arg_repetition = eArgRepeatPlain;
1753
1754 // There is only one variant this argument could be; put it into the argument entry.
1755 arg1.push_back (cmd_arg);
1756
1757 // Push the data for the first argument into the m_arguments vector.
1758 m_arguments.push_back (arg1);
1759 }
1760
1761 ~CommandObjectCommandsScriptAdd ()
1762 {
1763 }
1764
1765 virtual Options *
1766 GetOptions ()
1767 {
1768 return &m_options;
1769 }
1770
1771protected:
Enrico Granata223383e2011-08-16 23:24:13 +00001772
1773 class CommandOptions : public Options
1774 {
1775 public:
1776
1777 CommandOptions (CommandInterpreter &interpreter) :
Enrico Granata9fe00e52015-03-13 02:20:41 +00001778 Options (interpreter),
1779 m_class_name(),
1780 m_funct_name(),
1781 m_short_help(),
1782 m_synchronicity(eScriptedCommandSynchronicitySynchronous)
Enrico Granata223383e2011-08-16 23:24:13 +00001783 {
1784 }
1785
1786 virtual
1787 ~CommandOptions (){}
1788
1789 virtual Error
1790 SetOptionValue (uint32_t option_idx, const char *option_arg)
1791 {
1792 Error error;
Greg Clayton3bcdfc02012-12-04 00:32:51 +00001793 const int short_option = m_getopt_table[option_idx].val;
Enrico Granata223383e2011-08-16 23:24:13 +00001794
1795 switch (short_option)
1796 {
1797 case 'f':
Enrico Granata735152e2014-09-15 17:52:44 +00001798 if (option_arg)
1799 m_funct_name.assign(option_arg);
1800 break;
Enrico Granata9fe00e52015-03-13 02:20:41 +00001801 case 'c':
1802 if (option_arg)
1803 m_class_name.assign(option_arg);
1804 break;
Enrico Granata735152e2014-09-15 17:52:44 +00001805 case 'h':
1806 if (option_arg)
1807 m_short_help.assign(option_arg);
Enrico Granata223383e2011-08-16 23:24:13 +00001808 break;
Enrico Granata0a305db2011-11-07 22:57:04 +00001809 case 's':
Greg Clayton44d93782014-01-27 23:43:24 +00001810 m_synchronicity = (ScriptedCommandSynchronicity) Args::StringToOptionEnum(option_arg, g_option_table[option_idx].enum_values, 0, error);
Enrico Granata0a305db2011-11-07 22:57:04 +00001811 if (!error.Success())
1812 error.SetErrorStringWithFormat ("unrecognized value for synchronicity '%s'", option_arg);
1813 break;
Enrico Granata223383e2011-08-16 23:24:13 +00001814 default:
Greg Clayton86edbf42011-10-26 00:56:27 +00001815 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
Enrico Granata223383e2011-08-16 23:24:13 +00001816 break;
1817 }
1818
1819 return error;
1820 }
1821
1822 void
1823 OptionParsingStarting ()
1824 {
Enrico Granata9fe00e52015-03-13 02:20:41 +00001825 m_class_name.clear();
Enrico Granata735152e2014-09-15 17:52:44 +00001826 m_funct_name.clear();
1827 m_short_help.clear();
Greg Clayton44d93782014-01-27 23:43:24 +00001828 m_synchronicity = eScriptedCommandSynchronicitySynchronous;
Enrico Granata223383e2011-08-16 23:24:13 +00001829 }
1830
1831 const OptionDefinition*
1832 GetDefinitions ()
1833 {
1834 return g_option_table;
1835 }
1836
1837 // Options table: Required for subclasses of Options.
1838
1839 static OptionDefinition g_option_table[];
1840
1841 // Instance variables to hold the values for command options.
1842
Enrico Granata9fe00e52015-03-13 02:20:41 +00001843 std::string m_class_name;
Enrico Granata223383e2011-08-16 23:24:13 +00001844 std::string m_funct_name;
Enrico Granata735152e2014-09-15 17:52:44 +00001845 std::string m_short_help;
Greg Clayton44d93782014-01-27 23:43:24 +00001846 ScriptedCommandSynchronicity m_synchronicity;
Enrico Granata223383e2011-08-16 23:24:13 +00001847 };
Jim Ingham5a988412012-06-08 21:56:10 +00001848
Greg Clayton44d93782014-01-27 23:43:24 +00001849 virtual void
1850 IOHandlerActivated (IOHandler &io_handler)
Enrico Granata223383e2011-08-16 23:24:13 +00001851 {
Greg Clayton44d93782014-01-27 23:43:24 +00001852 StreamFileSP output_sp(io_handler.GetOutputStreamFile());
1853 if (output_sp)
Enrico Granata223383e2011-08-16 23:24:13 +00001854 {
Greg Clayton44d93782014-01-27 23:43:24 +00001855 output_sp->PutCString(g_python_command_instructions);
1856 output_sp->Flush();
Enrico Granata223383e2011-08-16 23:24:13 +00001857 }
Greg Clayton44d93782014-01-27 23:43:24 +00001858 }
Enrico Granata223383e2011-08-16 23:24:13 +00001859
Greg Clayton44d93782014-01-27 23:43:24 +00001860
1861 virtual void
1862 IOHandlerInputComplete (IOHandler &io_handler, std::string &data)
1863 {
1864 StreamFileSP error_sp = io_handler.GetErrorStreamFile();
1865
1866 ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter();
1867 if (interpreter)
1868 {
1869
1870 StringList lines;
1871 lines.SplitIntoLines(data);
1872 if (lines.GetSize() > 0)
1873 {
1874 std::string funct_name_str;
1875 if (interpreter->GenerateScriptAliasFunction (lines, funct_name_str))
1876 {
1877 if (funct_name_str.empty())
1878 {
1879 error_sp->Printf ("error: unable to obtain a function name, didn't add python command.\n");
1880 error_sp->Flush();
1881 }
1882 else
1883 {
1884 // everything should be fine now, let's add this alias
1885
1886 CommandObjectSP command_obj_sp(new CommandObjectPythonFunction (m_interpreter,
1887 m_cmd_name,
1888 funct_name_str.c_str(),
Enrico Granata735152e2014-09-15 17:52:44 +00001889 m_short_help,
Greg Clayton44d93782014-01-27 23:43:24 +00001890 m_synchronicity));
1891
1892 if (!m_interpreter.AddUserCommand(m_cmd_name, command_obj_sp, true))
1893 {
1894 error_sp->Printf ("error: unable to add selected command, didn't add python command.\n");
1895 error_sp->Flush();
1896 }
1897 }
1898 }
1899 else
1900 {
1901 error_sp->Printf ("error: unable to create function, didn't add python command.\n");
1902 error_sp->Flush();
1903 }
1904 }
1905 else
1906 {
1907 error_sp->Printf ("error: empty function, didn't add python command.\n");
1908 error_sp->Flush();
1909 }
1910 }
1911 else
1912 {
1913 error_sp->Printf ("error: script interpreter missing, didn't add python command.\n");
1914 error_sp->Flush();
1915 }
1916
1917 io_handler.SetIsDone(true);
1918
1919
1920 }
1921
Jim Ingham5a988412012-06-08 21:56:10 +00001922protected:
Enrico Granata223383e2011-08-16 23:24:13 +00001923 bool
Jim Ingham5a988412012-06-08 21:56:10 +00001924 DoExecute (Args& command, CommandReturnObject &result)
Enrico Granata223383e2011-08-16 23:24:13 +00001925 {
Enrico Granata99f0b8f2011-08-17 01:30:04 +00001926
1927 if (m_interpreter.GetDebugger().GetScriptLanguage() != lldb::eScriptLanguagePython)
1928 {
1929 result.AppendError ("only scripting language supported for scripted commands is currently Python");
1930 result.SetStatus (eReturnStatusFailed);
1931 return false;
1932 }
1933
Jim Ingham5a988412012-06-08 21:56:10 +00001934 size_t argc = command.GetArgumentCount();
Enrico Granata223383e2011-08-16 23:24:13 +00001935
1936 if (argc != 1)
1937 {
1938 result.AppendError ("'command script add' requires one argument");
1939 result.SetStatus (eReturnStatusFailed);
1940 return false;
1941 }
1942
Enrico Granata735152e2014-09-15 17:52:44 +00001943 // Store the options in case we get multi-line input
Greg Clayton44d93782014-01-27 23:43:24 +00001944 m_cmd_name = command.GetArgumentAtIndex(0);
Enrico Granata735152e2014-09-15 17:52:44 +00001945 m_short_help.assign(m_options.m_short_help);
Greg Clayton44d93782014-01-27 23:43:24 +00001946 m_synchronicity = m_options.m_synchronicity;
Enrico Granata223383e2011-08-16 23:24:13 +00001947
Enrico Granata9fe00e52015-03-13 02:20:41 +00001948 if (m_options.m_class_name.empty())
Enrico Granata223383e2011-08-16 23:24:13 +00001949 {
Enrico Granata9fe00e52015-03-13 02:20:41 +00001950 if (m_options.m_funct_name.empty())
1951 {
1952 m_interpreter.GetPythonCommandsFromIOHandler (" ", // Prompt
1953 *this, // IOHandlerDelegate
1954 true, // Run IOHandler in async mode
1955 NULL); // Baton for the "io_handler" that will be passed back into our IOHandlerDelegate functions
1956 }
1957 else
1958 {
1959 CommandObjectSP new_cmd(new CommandObjectPythonFunction(m_interpreter,
1960 m_cmd_name,
1961 m_options.m_funct_name,
1962 m_options.m_short_help,
1963 m_synchronicity));
1964 if (m_interpreter.AddUserCommand(m_cmd_name, new_cmd, true))
1965 {
1966 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1967 }
1968 else
1969 {
1970 result.AppendError("cannot add command");
1971 result.SetStatus (eReturnStatusFailed);
1972 }
1973 }
Enrico Granata223383e2011-08-16 23:24:13 +00001974 }
1975 else
1976 {
Enrico Granata9fe00e52015-03-13 02:20:41 +00001977 ScriptInterpreter *interpreter = GetCommandInterpreter().GetScriptInterpreter();
1978 if (!interpreter)
1979 {
1980 result.AppendError("cannot find ScriptInterpreter");
1981 result.SetStatus(eReturnStatusFailed);
1982 return false;
1983 }
1984
1985 auto cmd_obj_sp = interpreter->CreateScriptCommandObject(m_options.m_class_name.c_str());
1986 if (!cmd_obj_sp)
1987 {
1988 result.AppendError("cannot create helper object");
1989 result.SetStatus(eReturnStatusFailed);
1990 return false;
1991 }
1992
1993 CommandObjectSP new_cmd(new CommandObjectScriptingObject(m_interpreter,
1994 m_cmd_name,
1995 cmd_obj_sp,
1996 m_synchronicity));
Greg Clayton44d93782014-01-27 23:43:24 +00001997 if (m_interpreter.AddUserCommand(m_cmd_name, new_cmd, true))
Enrico Granata223383e2011-08-16 23:24:13 +00001998 {
1999 result.SetStatus (eReturnStatusSuccessFinishNoResult);
2000 }
2001 else
2002 {
2003 result.AppendError("cannot add command");
2004 result.SetStatus (eReturnStatusFailed);
2005 }
2006 }
2007
2008 return result.Succeeded();
2009
2010 }
Jim Ingham5a988412012-06-08 21:56:10 +00002011
2012 CommandOptions m_options;
Greg Clayton44d93782014-01-27 23:43:24 +00002013 std::string m_cmd_name;
Enrico Granata735152e2014-09-15 17:52:44 +00002014 std::string m_short_help;
Greg Clayton44d93782014-01-27 23:43:24 +00002015 ScriptedCommandSynchronicity m_synchronicity;
Enrico Granata223383e2011-08-16 23:24:13 +00002016};
2017
Enrico Granata0a305db2011-11-07 22:57:04 +00002018static OptionEnumValueElement g_script_synchro_type[] =
2019{
2020 { eScriptedCommandSynchronicitySynchronous, "synchronous", "Run synchronous"},
2021 { eScriptedCommandSynchronicityAsynchronous, "asynchronous", "Run asynchronous"},
2022 { eScriptedCommandSynchronicityCurrentValue, "current", "Do not alter current setting"},
2023 { 0, NULL, NULL }
2024};
2025
Enrico Granata223383e2011-08-16 23:24:13 +00002026OptionDefinition
2027CommandObjectCommandsScriptAdd::CommandOptions::g_option_table[] =
2028{
Zachary Turnerd37221d2014-07-09 16:31:49 +00002029 { LLDB_OPT_SET_1, false, "function", 'f', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypePythonFunction, "Name of the Python function to bind to this command name."},
Enrico Granata9fe00e52015-03-13 02:20:41 +00002030 { LLDB_OPT_SET_2, false, "class", 'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypePythonClass, "Name of the Python class to bind to this command name."},
Enrico Granata9370d272015-03-13 22:35:44 +00002031 { LLDB_OPT_SET_1, false, "help" , 'h', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeHelpText, "The help text to display for this command."},
Enrico Granata9fe00e52015-03-13 02:20:41 +00002032 { LLDB_OPT_SET_ALL, false, "synchronicity", 's', OptionParser::eRequiredArgument, NULL, g_script_synchro_type, 0, eArgTypeScriptedCommandSynchronicity, "Set the synchronicity of this command's executions with regard to LLDB event system."},
Zachary Turnerd37221d2014-07-09 16:31:49 +00002033 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
Enrico Granata223383e2011-08-16 23:24:13 +00002034};
2035
2036//-------------------------------------------------------------------------
2037// CommandObjectCommandsScriptList
2038//-------------------------------------------------------------------------
2039
Jim Ingham5a988412012-06-08 21:56:10 +00002040class CommandObjectCommandsScriptList : public CommandObjectParsed
Enrico Granata223383e2011-08-16 23:24:13 +00002041{
2042private:
Enrico Granata0a305db2011-11-07 22:57:04 +00002043
Enrico Granata223383e2011-08-16 23:24:13 +00002044public:
2045 CommandObjectCommandsScriptList(CommandInterpreter &interpreter) :
Jim Ingham5a988412012-06-08 21:56:10 +00002046 CommandObjectParsed (interpreter,
Enrico Granata223383e2011-08-16 23:24:13 +00002047 "command script list",
2048 "List defined scripted commands.",
2049 NULL)
2050 {
2051 }
2052
2053 ~CommandObjectCommandsScriptList ()
2054 {
2055 }
2056
2057 bool
Jim Ingham5a988412012-06-08 21:56:10 +00002058 DoExecute (Args& command, CommandReturnObject &result)
Enrico Granata223383e2011-08-16 23:24:13 +00002059 {
2060
2061 m_interpreter.GetHelp(result,
2062 CommandInterpreter::eCommandTypesUserDef);
2063
2064 result.SetStatus (eReturnStatusSuccessFinishResult);
2065
2066 return true;
2067
2068
2069 }
2070};
2071
2072//-------------------------------------------------------------------------
2073// CommandObjectCommandsScriptClear
2074//-------------------------------------------------------------------------
2075
Jim Ingham5a988412012-06-08 21:56:10 +00002076class CommandObjectCommandsScriptClear : public CommandObjectParsed
Enrico Granata223383e2011-08-16 23:24:13 +00002077{
2078private:
2079
2080public:
2081 CommandObjectCommandsScriptClear(CommandInterpreter &interpreter) :
Jim Ingham5a988412012-06-08 21:56:10 +00002082 CommandObjectParsed (interpreter,
2083 "command script clear",
2084 "Delete all scripted commands.",
2085 NULL)
Enrico Granata223383e2011-08-16 23:24:13 +00002086 {
2087 }
2088
2089 ~CommandObjectCommandsScriptClear ()
2090 {
2091 }
2092
Jim Ingham5a988412012-06-08 21:56:10 +00002093protected:
Enrico Granata223383e2011-08-16 23:24:13 +00002094 bool
Jim Ingham5a988412012-06-08 21:56:10 +00002095 DoExecute (Args& command, CommandReturnObject &result)
Enrico Granata223383e2011-08-16 23:24:13 +00002096 {
2097
2098 m_interpreter.RemoveAllUser();
2099
2100 result.SetStatus (eReturnStatusSuccessFinishResult);
2101
2102 return true;
Enrico Granata223383e2011-08-16 23:24:13 +00002103 }
2104};
2105
2106//-------------------------------------------------------------------------
2107// CommandObjectCommandsScriptDelete
2108//-------------------------------------------------------------------------
2109
Jim Ingham5a988412012-06-08 21:56:10 +00002110class CommandObjectCommandsScriptDelete : public CommandObjectParsed
Enrico Granata223383e2011-08-16 23:24:13 +00002111{
Enrico Granata223383e2011-08-16 23:24:13 +00002112public:
2113 CommandObjectCommandsScriptDelete(CommandInterpreter &interpreter) :
Jim Ingham5a988412012-06-08 21:56:10 +00002114 CommandObjectParsed (interpreter,
2115 "command script delete",
2116 "Delete a scripted command.",
2117 NULL)
Enrico Granata223383e2011-08-16 23:24:13 +00002118 {
2119 CommandArgumentEntry arg1;
2120 CommandArgumentData cmd_arg;
2121
2122 // Define the first (and only) variant of this arg.
2123 cmd_arg.arg_type = eArgTypeCommandName;
2124 cmd_arg.arg_repetition = eArgRepeatPlain;
2125
2126 // There is only one variant this argument could be; put it into the argument entry.
2127 arg1.push_back (cmd_arg);
2128
2129 // Push the data for the first argument into the m_arguments vector.
2130 m_arguments.push_back (arg1);
2131 }
2132
2133 ~CommandObjectCommandsScriptDelete ()
2134 {
2135 }
2136
Jim Ingham5a988412012-06-08 21:56:10 +00002137protected:
Enrico Granata223383e2011-08-16 23:24:13 +00002138 bool
Jim Ingham5a988412012-06-08 21:56:10 +00002139 DoExecute (Args& command, CommandReturnObject &result)
Enrico Granata223383e2011-08-16 23:24:13 +00002140 {
2141
Jim Ingham5a988412012-06-08 21:56:10 +00002142 size_t argc = command.GetArgumentCount();
Enrico Granata223383e2011-08-16 23:24:13 +00002143
2144 if (argc != 1)
2145 {
2146 result.AppendError ("'command script delete' requires one argument");
2147 result.SetStatus (eReturnStatusFailed);
2148 return false;
2149 }
2150
Jim Ingham5a988412012-06-08 21:56:10 +00002151 const char* cmd_name = command.GetArgumentAtIndex(0);
Enrico Granata223383e2011-08-16 23:24:13 +00002152
2153 if (cmd_name && *cmd_name && m_interpreter.HasUserCommands() && m_interpreter.UserCommandExists(cmd_name))
2154 {
2155 m_interpreter.RemoveUser(cmd_name);
2156 result.SetStatus (eReturnStatusSuccessFinishResult);
2157 }
2158 else
2159 {
2160 result.AppendErrorWithFormat ("command %s not found", cmd_name);
2161 result.SetStatus (eReturnStatusFailed);
2162 }
2163
2164 return result.Succeeded();
2165
2166 }
2167};
2168
2169#pragma mark CommandObjectMultiwordCommandsScript
2170
2171//-------------------------------------------------------------------------
2172// CommandObjectMultiwordCommandsScript
2173//-------------------------------------------------------------------------
2174
2175class CommandObjectMultiwordCommandsScript : public CommandObjectMultiword
2176{
2177public:
2178 CommandObjectMultiwordCommandsScript (CommandInterpreter &interpreter) :
2179 CommandObjectMultiword (interpreter,
2180 "command script",
2181 "A set of commands for managing or customizing script commands.",
2182 "command script <subcommand> [<subcommand-options>]")
2183 {
Greg Claytonb5472782015-01-09 19:08:20 +00002184 LoadSubCommand ("add", CommandObjectSP (new CommandObjectCommandsScriptAdd (interpreter)));
2185 LoadSubCommand ("delete", CommandObjectSP (new CommandObjectCommandsScriptDelete (interpreter)));
2186 LoadSubCommand ("clear", CommandObjectSP (new CommandObjectCommandsScriptClear (interpreter)));
Enrico Granata223383e2011-08-16 23:24:13 +00002187 LoadSubCommand ("list", CommandObjectSP (new CommandObjectCommandsScriptList (interpreter)));
Greg Claytonb5472782015-01-09 19:08:20 +00002188 LoadSubCommand ("import", CommandObjectSP (new CommandObjectCommandsScriptImport (interpreter)));
Enrico Granata223383e2011-08-16 23:24:13 +00002189 }
2190
2191 ~CommandObjectMultiwordCommandsScript ()
2192 {
2193 }
2194
2195};
2196
2197
Jim Inghamebc09c32010-07-07 03:36:20 +00002198#pragma mark CommandObjectMultiwordCommands
2199
2200//-------------------------------------------------------------------------
2201// CommandObjectMultiwordCommands
2202//-------------------------------------------------------------------------
2203
2204CommandObjectMultiwordCommands::CommandObjectMultiwordCommands (CommandInterpreter &interpreter) :
Greg Claytona7015092010-09-18 01:14:36 +00002205 CommandObjectMultiword (interpreter,
Greg Clayton0e5e5a72011-04-20 22:55:21 +00002206 "command",
Caroline Tice3f4c09c2010-09-07 22:38:08 +00002207 "A set of commands for managing or customizing the debugger commands.",
Greg Clayton0e5e5a72011-04-20 22:55:21 +00002208 "command <subcommand> [<subcommand-options>]")
Jim Inghamebc09c32010-07-07 03:36:20 +00002209{
Greg Claytona7015092010-09-18 01:14:36 +00002210 LoadSubCommand ("source", CommandObjectSP (new CommandObjectCommandsSource (interpreter)));
2211 LoadSubCommand ("alias", CommandObjectSP (new CommandObjectCommandsAlias (interpreter)));
2212 LoadSubCommand ("unalias", CommandObjectSP (new CommandObjectCommandsUnalias (interpreter)));
Greg Claytonb5472782015-01-09 19:08:20 +00002213 LoadSubCommand ("delete", CommandObjectSP (new CommandObjectCommandsDelete (interpreter)));
Greg Claytonde164aa2011-04-20 16:37:46 +00002214 LoadSubCommand ("regex", CommandObjectSP (new CommandObjectCommandsAddRegex (interpreter)));
Greg Claytonb5472782015-01-09 19:08:20 +00002215 LoadSubCommand ("history", CommandObjectSP (new CommandObjectCommandsHistory (interpreter)));
2216 LoadSubCommand ("script", CommandObjectSP (new CommandObjectMultiwordCommandsScript (interpreter)));
Jim Inghamebc09c32010-07-07 03:36:20 +00002217}
2218
2219CommandObjectMultiwordCommands::~CommandObjectMultiwordCommands ()
2220{
2221}
2222