blob: 2946a0ba4be5a141de2cd34d6cff9471bd5b5c4e [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());
1458 }
1459
1460 virtual
1461 ~CommandObjectScriptingObject ()
1462 {
1463 }
1464
1465 virtual bool
1466 IsRemovable () const
1467 {
1468 return true;
1469 }
1470
Zachary Turner0641ca12015-03-17 20:04:04 +00001471 StructuredData::GenericSP
Enrico Granata9fe00e52015-03-13 02:20:41 +00001472 GetImplementingObject ()
1473 {
1474 return m_cmd_obj_sp;
1475 }
1476
1477 ScriptedCommandSynchronicity
1478 GetSynchronicity ()
1479 {
1480 return m_synchro;
1481 }
Enrico Granata6f79bb22015-03-13 22:22:28 +00001482
1483 virtual const char *
1484 GetHelp ()
1485 {
1486 if (!m_fetched_help_short)
1487 {
1488 ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter();
1489 if (scripter)
1490 {
1491 std::string docstring;
1492 m_fetched_help_short = scripter->GetShortHelpForCommandObject(m_cmd_obj_sp,docstring);
1493 if (!docstring.empty())
1494 SetHelp(docstring);
1495 }
1496 }
1497 return CommandObjectRaw::GetHelp();
1498 }
Enrico Granata9fe00e52015-03-13 02:20:41 +00001499
1500 virtual const char *
1501 GetHelpLong ()
1502 {
Enrico Granata6f79bb22015-03-13 22:22:28 +00001503 if (!m_fetched_help_long)
1504 {
1505 ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter();
1506 if (scripter)
1507 {
1508 std::string docstring;
1509 m_fetched_help_long = scripter->GetLongHelpForCommandObject(m_cmd_obj_sp,docstring);
1510 if (!docstring.empty())
1511 SetHelpLong(docstring);
1512 }
1513 }
Enrico Granata9fe00e52015-03-13 02:20:41 +00001514 return CommandObjectRaw::GetHelpLong();
1515 }
1516
1517protected:
1518 virtual bool
1519 DoExecute (const char *raw_command_line, CommandReturnObject &result)
1520 {
1521 ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter();
1522
1523 Error error;
1524
1525 result.SetStatus(eReturnStatusInvalid);
1526
1527 if (!scripter || scripter->RunScriptBasedCommand(m_cmd_obj_sp,
1528 raw_command_line,
1529 m_synchro,
1530 result,
1531 error,
1532 m_exe_ctx) == false)
1533 {
1534 result.AppendError(error.AsCString());
1535 result.SetStatus(eReturnStatusFailed);
1536 }
1537 else
1538 {
1539 // Don't change the status if the command already set it...
1540 if (result.GetStatus() == eReturnStatusInvalid)
1541 {
1542 if (result.GetOutputData() == NULL || result.GetOutputData()[0] == '\0')
1543 result.SetStatus(eReturnStatusSuccessFinishNoResult);
1544 else
1545 result.SetStatus(eReturnStatusSuccessFinishResult);
1546 }
1547 }
1548
1549 return result.Succeeded();
1550 }
1551
1552};
1553
Enrico Granataa9dbf432011-10-17 21:45:27 +00001554//-------------------------------------------------------------------------
1555// CommandObjectCommandsScriptImport
1556//-------------------------------------------------------------------------
1557
Jim Ingham5a988412012-06-08 21:56:10 +00001558class CommandObjectCommandsScriptImport : public CommandObjectParsed
Enrico Granataa9dbf432011-10-17 21:45:27 +00001559{
Jim Ingham5a988412012-06-08 21:56:10 +00001560public:
1561 CommandObjectCommandsScriptImport (CommandInterpreter &interpreter) :
1562 CommandObjectParsed (interpreter,
1563 "command script import",
1564 "Import a scripting module in LLDB.",
1565 NULL),
1566 m_options(interpreter)
1567 {
1568 CommandArgumentEntry arg1;
1569 CommandArgumentData cmd_arg;
1570
1571 // Define the first (and only) variant of this arg.
1572 cmd_arg.arg_type = eArgTypeFilename;
1573 cmd_arg.arg_repetition = eArgRepeatPlain;
1574
1575 // There is only one variant this argument could be; put it into the argument entry.
1576 arg1.push_back (cmd_arg);
1577
1578 // Push the data for the first argument into the m_arguments vector.
1579 m_arguments.push_back (arg1);
1580 }
1581
1582 ~CommandObjectCommandsScriptImport ()
1583 {
1584 }
1585
Greg Claytonc7bece562013-01-25 18:06:21 +00001586 virtual int
Jim Ingham5a988412012-06-08 21:56:10 +00001587 HandleArgumentCompletion (Args &input,
1588 int &cursor_index,
1589 int &cursor_char_position,
1590 OptionElementVector &opt_element_vector,
1591 int match_start_point,
1592 int max_return_elements,
1593 bool &word_complete,
1594 StringList &matches)
1595 {
1596 std::string completion_str (input.GetArgumentAtIndex(cursor_index));
1597 completion_str.erase (cursor_char_position);
1598
1599 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
1600 CommandCompletions::eDiskFileCompletion,
1601 completion_str.c_str(),
1602 match_start_point,
1603 max_return_elements,
1604 NULL,
1605 word_complete,
1606 matches);
1607 return matches.GetSize();
1608 }
1609
1610 virtual Options *
1611 GetOptions ()
1612 {
1613 return &m_options;
1614 }
1615
1616protected:
Enrico Granata0a305db2011-11-07 22:57:04 +00001617
1618 class CommandOptions : public Options
1619 {
1620 public:
1621
1622 CommandOptions (CommandInterpreter &interpreter) :
Jim Ingham5a988412012-06-08 21:56:10 +00001623 Options (interpreter)
Enrico Granata0a305db2011-11-07 22:57:04 +00001624 {
1625 }
1626
1627 virtual
1628 ~CommandOptions (){}
1629
1630 virtual Error
1631 SetOptionValue (uint32_t option_idx, const char *option_arg)
1632 {
1633 Error error;
Greg Clayton3bcdfc02012-12-04 00:32:51 +00001634 const int short_option = m_getopt_table[option_idx].val;
Enrico Granata0a305db2011-11-07 22:57:04 +00001635
1636 switch (short_option)
1637 {
1638 case 'r':
1639 m_allow_reload = true;
1640 break;
1641 default:
1642 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1643 break;
1644 }
1645
1646 return error;
1647 }
1648
1649 void
1650 OptionParsingStarting ()
1651 {
Enrico Granatae0c70f12013-05-31 01:03:09 +00001652 m_allow_reload = true;
Enrico Granata0a305db2011-11-07 22:57:04 +00001653 }
1654
1655 const OptionDefinition*
1656 GetDefinitions ()
1657 {
1658 return g_option_table;
1659 }
1660
1661 // Options table: Required for subclasses of Options.
1662
1663 static OptionDefinition g_option_table[];
1664
1665 // Instance variables to hold the values for command options.
1666
1667 bool m_allow_reload;
1668 };
Enrico Granata0a305db2011-11-07 22:57:04 +00001669
Enrico Granataa9dbf432011-10-17 21:45:27 +00001670 bool
Jim Ingham5a988412012-06-08 21:56:10 +00001671 DoExecute (Args& command, CommandReturnObject &result)
Enrico Granataa9dbf432011-10-17 21:45:27 +00001672 {
1673
1674 if (m_interpreter.GetDebugger().GetScriptLanguage() != lldb::eScriptLanguagePython)
1675 {
1676 result.AppendError ("only scripting language supported for module importing is currently Python");
1677 result.SetStatus (eReturnStatusFailed);
1678 return false;
1679 }
1680
Jim Ingham5a988412012-06-08 21:56:10 +00001681 size_t argc = command.GetArgumentCount();
Enrico Granataa9dbf432011-10-17 21:45:27 +00001682
1683 if (argc != 1)
1684 {
1685 result.AppendError ("'command script import' requires one argument");
1686 result.SetStatus (eReturnStatusFailed);
1687 return false;
1688 }
1689
Jim Ingham5a988412012-06-08 21:56:10 +00001690 std::string path = command.GetArgumentAtIndex(0);
Enrico Granataa9dbf432011-10-17 21:45:27 +00001691 Error error;
1692
Greg Claytonc9d645d2012-10-18 22:40:37 +00001693 const bool init_session = true;
Enrico Granata078551c2013-05-09 19:33:49 +00001694 // FIXME: this is necessary because CommandObject::CheckRequirements() assumes that
1695 // commands won't ever be recursively invoked, but it's actually possible to craft
1696 // a Python script that does other "command script imports" in __lldb_init_module
1697 // the real fix is to have recursive commands possible with a CommandInvocation object
1698 // separate from the CommandObject itself, so that recursive command invocations
1699 // won't stomp on each other (wrt to execution contents, options, and more)
1700 m_exe_ctx.Clear();
Enrico Granataa9dbf432011-10-17 21:45:27 +00001701 if (m_interpreter.GetScriptInterpreter()->LoadScriptingModule(path.c_str(),
Enrico Granata0a305db2011-11-07 22:57:04 +00001702 m_options.m_allow_reload,
Greg Claytonc9d645d2012-10-18 22:40:37 +00001703 init_session,
Enrico Granataa9dbf432011-10-17 21:45:27 +00001704 error))
1705 {
1706 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1707 }
1708 else
1709 {
1710 result.AppendErrorWithFormat("module importing failed: %s", error.AsCString());
1711 result.SetStatus (eReturnStatusFailed);
1712 }
1713
1714 return result.Succeeded();
1715 }
Enrico Granata0a305db2011-11-07 22:57:04 +00001716
Jim Ingham5a988412012-06-08 21:56:10 +00001717 CommandOptions m_options;
Enrico Granataa9dbf432011-10-17 21:45:27 +00001718};
Enrico Granata223383e2011-08-16 23:24:13 +00001719
Enrico Granata0a305db2011-11-07 22:57:04 +00001720OptionDefinition
1721CommandObjectCommandsScriptImport::CommandOptions::g_option_table[] =
1722{
Zachary Turnerd37221d2014-07-09 16:31:49 +00001723 { 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."},
1724 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
Enrico Granata0a305db2011-11-07 22:57:04 +00001725};
1726
1727
Enrico Granata223383e2011-08-16 23:24:13 +00001728//-------------------------------------------------------------------------
1729// CommandObjectCommandsScriptAdd
1730//-------------------------------------------------------------------------
1731
Greg Clayton44d93782014-01-27 23:43:24 +00001732class CommandObjectCommandsScriptAdd :
1733 public CommandObjectParsed,
1734 public IOHandlerDelegateMultiline
Enrico Granata223383e2011-08-16 23:24:13 +00001735{
Jim Ingham5a988412012-06-08 21:56:10 +00001736public:
1737 CommandObjectCommandsScriptAdd(CommandInterpreter &interpreter) :
1738 CommandObjectParsed (interpreter,
1739 "command script add",
1740 "Add a scripted function as an LLDB command.",
1741 NULL),
Greg Claytonc3d874a2014-05-08 16:59:00 +00001742 IOHandlerDelegateMultiline ("DONE"),
Jim Ingham5a988412012-06-08 21:56:10 +00001743 m_options (interpreter)
1744 {
1745 CommandArgumentEntry arg1;
1746 CommandArgumentData cmd_arg;
1747
1748 // Define the first (and only) variant of this arg.
1749 cmd_arg.arg_type = eArgTypeCommandName;
1750 cmd_arg.arg_repetition = eArgRepeatPlain;
1751
1752 // There is only one variant this argument could be; put it into the argument entry.
1753 arg1.push_back (cmd_arg);
1754
1755 // Push the data for the first argument into the m_arguments vector.
1756 m_arguments.push_back (arg1);
1757 }
1758
1759 ~CommandObjectCommandsScriptAdd ()
1760 {
1761 }
1762
1763 virtual Options *
1764 GetOptions ()
1765 {
1766 return &m_options;
1767 }
1768
1769protected:
Enrico Granata223383e2011-08-16 23:24:13 +00001770
1771 class CommandOptions : public Options
1772 {
1773 public:
1774
1775 CommandOptions (CommandInterpreter &interpreter) :
Enrico Granata9fe00e52015-03-13 02:20:41 +00001776 Options (interpreter),
1777 m_class_name(),
1778 m_funct_name(),
1779 m_short_help(),
1780 m_synchronicity(eScriptedCommandSynchronicitySynchronous)
Enrico Granata223383e2011-08-16 23:24:13 +00001781 {
1782 }
1783
1784 virtual
1785 ~CommandOptions (){}
1786
1787 virtual Error
1788 SetOptionValue (uint32_t option_idx, const char *option_arg)
1789 {
1790 Error error;
Greg Clayton3bcdfc02012-12-04 00:32:51 +00001791 const int short_option = m_getopt_table[option_idx].val;
Enrico Granata223383e2011-08-16 23:24:13 +00001792
1793 switch (short_option)
1794 {
1795 case 'f':
Enrico Granata735152e2014-09-15 17:52:44 +00001796 if (option_arg)
1797 m_funct_name.assign(option_arg);
1798 break;
Enrico Granata9fe00e52015-03-13 02:20:41 +00001799 case 'c':
1800 if (option_arg)
1801 m_class_name.assign(option_arg);
1802 break;
Enrico Granata735152e2014-09-15 17:52:44 +00001803 case 'h':
1804 if (option_arg)
1805 m_short_help.assign(option_arg);
Enrico Granata223383e2011-08-16 23:24:13 +00001806 break;
Enrico Granata0a305db2011-11-07 22:57:04 +00001807 case 's':
Greg Clayton44d93782014-01-27 23:43:24 +00001808 m_synchronicity = (ScriptedCommandSynchronicity) Args::StringToOptionEnum(option_arg, g_option_table[option_idx].enum_values, 0, error);
Enrico Granata0a305db2011-11-07 22:57:04 +00001809 if (!error.Success())
1810 error.SetErrorStringWithFormat ("unrecognized value for synchronicity '%s'", option_arg);
1811 break;
Enrico Granata223383e2011-08-16 23:24:13 +00001812 default:
Greg Clayton86edbf42011-10-26 00:56:27 +00001813 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
Enrico Granata223383e2011-08-16 23:24:13 +00001814 break;
1815 }
1816
1817 return error;
1818 }
1819
1820 void
1821 OptionParsingStarting ()
1822 {
Enrico Granata9fe00e52015-03-13 02:20:41 +00001823 m_class_name.clear();
Enrico Granata735152e2014-09-15 17:52:44 +00001824 m_funct_name.clear();
1825 m_short_help.clear();
Greg Clayton44d93782014-01-27 23:43:24 +00001826 m_synchronicity = eScriptedCommandSynchronicitySynchronous;
Enrico Granata223383e2011-08-16 23:24:13 +00001827 }
1828
1829 const OptionDefinition*
1830 GetDefinitions ()
1831 {
1832 return g_option_table;
1833 }
1834
1835 // Options table: Required for subclasses of Options.
1836
1837 static OptionDefinition g_option_table[];
1838
1839 // Instance variables to hold the values for command options.
1840
Enrico Granata9fe00e52015-03-13 02:20:41 +00001841 std::string m_class_name;
Enrico Granata223383e2011-08-16 23:24:13 +00001842 std::string m_funct_name;
Enrico Granata735152e2014-09-15 17:52:44 +00001843 std::string m_short_help;
Greg Clayton44d93782014-01-27 23:43:24 +00001844 ScriptedCommandSynchronicity m_synchronicity;
Enrico Granata223383e2011-08-16 23:24:13 +00001845 };
Jim Ingham5a988412012-06-08 21:56:10 +00001846
Greg Clayton44d93782014-01-27 23:43:24 +00001847 virtual void
1848 IOHandlerActivated (IOHandler &io_handler)
Enrico Granata223383e2011-08-16 23:24:13 +00001849 {
Greg Clayton44d93782014-01-27 23:43:24 +00001850 StreamFileSP output_sp(io_handler.GetOutputStreamFile());
1851 if (output_sp)
Enrico Granata223383e2011-08-16 23:24:13 +00001852 {
Greg Clayton44d93782014-01-27 23:43:24 +00001853 output_sp->PutCString(g_python_command_instructions);
1854 output_sp->Flush();
Enrico Granata223383e2011-08-16 23:24:13 +00001855 }
Greg Clayton44d93782014-01-27 23:43:24 +00001856 }
Enrico Granata223383e2011-08-16 23:24:13 +00001857
Greg Clayton44d93782014-01-27 23:43:24 +00001858
1859 virtual void
1860 IOHandlerInputComplete (IOHandler &io_handler, std::string &data)
1861 {
1862 StreamFileSP error_sp = io_handler.GetErrorStreamFile();
1863
1864 ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter();
1865 if (interpreter)
1866 {
1867
1868 StringList lines;
1869 lines.SplitIntoLines(data);
1870 if (lines.GetSize() > 0)
1871 {
1872 std::string funct_name_str;
1873 if (interpreter->GenerateScriptAliasFunction (lines, funct_name_str))
1874 {
1875 if (funct_name_str.empty())
1876 {
1877 error_sp->Printf ("error: unable to obtain a function name, didn't add python command.\n");
1878 error_sp->Flush();
1879 }
1880 else
1881 {
1882 // everything should be fine now, let's add this alias
1883
1884 CommandObjectSP command_obj_sp(new CommandObjectPythonFunction (m_interpreter,
1885 m_cmd_name,
1886 funct_name_str.c_str(),
Enrico Granata735152e2014-09-15 17:52:44 +00001887 m_short_help,
Greg Clayton44d93782014-01-27 23:43:24 +00001888 m_synchronicity));
1889
1890 if (!m_interpreter.AddUserCommand(m_cmd_name, command_obj_sp, true))
1891 {
1892 error_sp->Printf ("error: unable to add selected command, didn't add python command.\n");
1893 error_sp->Flush();
1894 }
1895 }
1896 }
1897 else
1898 {
1899 error_sp->Printf ("error: unable to create function, didn't add python command.\n");
1900 error_sp->Flush();
1901 }
1902 }
1903 else
1904 {
1905 error_sp->Printf ("error: empty function, didn't add python command.\n");
1906 error_sp->Flush();
1907 }
1908 }
1909 else
1910 {
1911 error_sp->Printf ("error: script interpreter missing, didn't add python command.\n");
1912 error_sp->Flush();
1913 }
1914
1915 io_handler.SetIsDone(true);
1916
1917
1918 }
1919
Jim Ingham5a988412012-06-08 21:56:10 +00001920protected:
Enrico Granata223383e2011-08-16 23:24:13 +00001921 bool
Jim Ingham5a988412012-06-08 21:56:10 +00001922 DoExecute (Args& command, CommandReturnObject &result)
Enrico Granata223383e2011-08-16 23:24:13 +00001923 {
Enrico Granata99f0b8f2011-08-17 01:30:04 +00001924
1925 if (m_interpreter.GetDebugger().GetScriptLanguage() != lldb::eScriptLanguagePython)
1926 {
1927 result.AppendError ("only scripting language supported for scripted commands is currently Python");
1928 result.SetStatus (eReturnStatusFailed);
1929 return false;
1930 }
1931
Jim Ingham5a988412012-06-08 21:56:10 +00001932 size_t argc = command.GetArgumentCount();
Enrico Granata223383e2011-08-16 23:24:13 +00001933
1934 if (argc != 1)
1935 {
1936 result.AppendError ("'command script add' requires one argument");
1937 result.SetStatus (eReturnStatusFailed);
1938 return false;
1939 }
1940
Enrico Granata735152e2014-09-15 17:52:44 +00001941 // Store the options in case we get multi-line input
Greg Clayton44d93782014-01-27 23:43:24 +00001942 m_cmd_name = command.GetArgumentAtIndex(0);
Enrico Granata735152e2014-09-15 17:52:44 +00001943 m_short_help.assign(m_options.m_short_help);
Greg Clayton44d93782014-01-27 23:43:24 +00001944 m_synchronicity = m_options.m_synchronicity;
Enrico Granata223383e2011-08-16 23:24:13 +00001945
Enrico Granata9fe00e52015-03-13 02:20:41 +00001946 if (m_options.m_class_name.empty())
Enrico Granata223383e2011-08-16 23:24:13 +00001947 {
Enrico Granata9fe00e52015-03-13 02:20:41 +00001948 if (m_options.m_funct_name.empty())
1949 {
1950 m_interpreter.GetPythonCommandsFromIOHandler (" ", // Prompt
1951 *this, // IOHandlerDelegate
1952 true, // Run IOHandler in async mode
1953 NULL); // Baton for the "io_handler" that will be passed back into our IOHandlerDelegate functions
1954 }
1955 else
1956 {
1957 CommandObjectSP new_cmd(new CommandObjectPythonFunction(m_interpreter,
1958 m_cmd_name,
1959 m_options.m_funct_name,
1960 m_options.m_short_help,
1961 m_synchronicity));
1962 if (m_interpreter.AddUserCommand(m_cmd_name, new_cmd, true))
1963 {
1964 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1965 }
1966 else
1967 {
1968 result.AppendError("cannot add command");
1969 result.SetStatus (eReturnStatusFailed);
1970 }
1971 }
Enrico Granata223383e2011-08-16 23:24:13 +00001972 }
1973 else
1974 {
Enrico Granata9fe00e52015-03-13 02:20:41 +00001975 ScriptInterpreter *interpreter = GetCommandInterpreter().GetScriptInterpreter();
1976 if (!interpreter)
1977 {
1978 result.AppendError("cannot find ScriptInterpreter");
1979 result.SetStatus(eReturnStatusFailed);
1980 return false;
1981 }
1982
1983 auto cmd_obj_sp = interpreter->CreateScriptCommandObject(m_options.m_class_name.c_str());
1984 if (!cmd_obj_sp)
1985 {
1986 result.AppendError("cannot create helper object");
1987 result.SetStatus(eReturnStatusFailed);
1988 return false;
1989 }
1990
1991 CommandObjectSP new_cmd(new CommandObjectScriptingObject(m_interpreter,
1992 m_cmd_name,
1993 cmd_obj_sp,
1994 m_synchronicity));
Greg Clayton44d93782014-01-27 23:43:24 +00001995 if (m_interpreter.AddUserCommand(m_cmd_name, new_cmd, true))
Enrico Granata223383e2011-08-16 23:24:13 +00001996 {
1997 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1998 }
1999 else
2000 {
2001 result.AppendError("cannot add command");
2002 result.SetStatus (eReturnStatusFailed);
2003 }
2004 }
2005
2006 return result.Succeeded();
2007
2008 }
Jim Ingham5a988412012-06-08 21:56:10 +00002009
2010 CommandOptions m_options;
Greg Clayton44d93782014-01-27 23:43:24 +00002011 std::string m_cmd_name;
Enrico Granata735152e2014-09-15 17:52:44 +00002012 std::string m_short_help;
Greg Clayton44d93782014-01-27 23:43:24 +00002013 ScriptedCommandSynchronicity m_synchronicity;
Enrico Granata223383e2011-08-16 23:24:13 +00002014};
2015
Enrico Granata0a305db2011-11-07 22:57:04 +00002016static OptionEnumValueElement g_script_synchro_type[] =
2017{
2018 { eScriptedCommandSynchronicitySynchronous, "synchronous", "Run synchronous"},
2019 { eScriptedCommandSynchronicityAsynchronous, "asynchronous", "Run asynchronous"},
2020 { eScriptedCommandSynchronicityCurrentValue, "current", "Do not alter current setting"},
2021 { 0, NULL, NULL }
2022};
2023
Enrico Granata223383e2011-08-16 23:24:13 +00002024OptionDefinition
2025CommandObjectCommandsScriptAdd::CommandOptions::g_option_table[] =
2026{
Zachary Turnerd37221d2014-07-09 16:31:49 +00002027 { 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 +00002028 { 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 +00002029 { 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 +00002030 { 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 +00002031 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
Enrico Granata223383e2011-08-16 23:24:13 +00002032};
2033
2034//-------------------------------------------------------------------------
2035// CommandObjectCommandsScriptList
2036//-------------------------------------------------------------------------
2037
Jim Ingham5a988412012-06-08 21:56:10 +00002038class CommandObjectCommandsScriptList : public CommandObjectParsed
Enrico Granata223383e2011-08-16 23:24:13 +00002039{
2040private:
Enrico Granata0a305db2011-11-07 22:57:04 +00002041
Enrico Granata223383e2011-08-16 23:24:13 +00002042public:
2043 CommandObjectCommandsScriptList(CommandInterpreter &interpreter) :
Jim Ingham5a988412012-06-08 21:56:10 +00002044 CommandObjectParsed (interpreter,
Enrico Granata223383e2011-08-16 23:24:13 +00002045 "command script list",
2046 "List defined scripted commands.",
2047 NULL)
2048 {
2049 }
2050
2051 ~CommandObjectCommandsScriptList ()
2052 {
2053 }
2054
2055 bool
Jim Ingham5a988412012-06-08 21:56:10 +00002056 DoExecute (Args& command, CommandReturnObject &result)
Enrico Granata223383e2011-08-16 23:24:13 +00002057 {
2058
2059 m_interpreter.GetHelp(result,
2060 CommandInterpreter::eCommandTypesUserDef);
2061
2062 result.SetStatus (eReturnStatusSuccessFinishResult);
2063
2064 return true;
2065
2066
2067 }
2068};
2069
2070//-------------------------------------------------------------------------
2071// CommandObjectCommandsScriptClear
2072//-------------------------------------------------------------------------
2073
Jim Ingham5a988412012-06-08 21:56:10 +00002074class CommandObjectCommandsScriptClear : public CommandObjectParsed
Enrico Granata223383e2011-08-16 23:24:13 +00002075{
2076private:
2077
2078public:
2079 CommandObjectCommandsScriptClear(CommandInterpreter &interpreter) :
Jim Ingham5a988412012-06-08 21:56:10 +00002080 CommandObjectParsed (interpreter,
2081 "command script clear",
2082 "Delete all scripted commands.",
2083 NULL)
Enrico Granata223383e2011-08-16 23:24:13 +00002084 {
2085 }
2086
2087 ~CommandObjectCommandsScriptClear ()
2088 {
2089 }
2090
Jim Ingham5a988412012-06-08 21:56:10 +00002091protected:
Enrico Granata223383e2011-08-16 23:24:13 +00002092 bool
Jim Ingham5a988412012-06-08 21:56:10 +00002093 DoExecute (Args& command, CommandReturnObject &result)
Enrico Granata223383e2011-08-16 23:24:13 +00002094 {
2095
2096 m_interpreter.RemoveAllUser();
2097
2098 result.SetStatus (eReturnStatusSuccessFinishResult);
2099
2100 return true;
Enrico Granata223383e2011-08-16 23:24:13 +00002101 }
2102};
2103
2104//-------------------------------------------------------------------------
2105// CommandObjectCommandsScriptDelete
2106//-------------------------------------------------------------------------
2107
Jim Ingham5a988412012-06-08 21:56:10 +00002108class CommandObjectCommandsScriptDelete : public CommandObjectParsed
Enrico Granata223383e2011-08-16 23:24:13 +00002109{
Enrico Granata223383e2011-08-16 23:24:13 +00002110public:
2111 CommandObjectCommandsScriptDelete(CommandInterpreter &interpreter) :
Jim Ingham5a988412012-06-08 21:56:10 +00002112 CommandObjectParsed (interpreter,
2113 "command script delete",
2114 "Delete a scripted command.",
2115 NULL)
Enrico Granata223383e2011-08-16 23:24:13 +00002116 {
2117 CommandArgumentEntry arg1;
2118 CommandArgumentData cmd_arg;
2119
2120 // Define the first (and only) variant of this arg.
2121 cmd_arg.arg_type = eArgTypeCommandName;
2122 cmd_arg.arg_repetition = eArgRepeatPlain;
2123
2124 // There is only one variant this argument could be; put it into the argument entry.
2125 arg1.push_back (cmd_arg);
2126
2127 // Push the data for the first argument into the m_arguments vector.
2128 m_arguments.push_back (arg1);
2129 }
2130
2131 ~CommandObjectCommandsScriptDelete ()
2132 {
2133 }
2134
Jim Ingham5a988412012-06-08 21:56:10 +00002135protected:
Enrico Granata223383e2011-08-16 23:24:13 +00002136 bool
Jim Ingham5a988412012-06-08 21:56:10 +00002137 DoExecute (Args& command, CommandReturnObject &result)
Enrico Granata223383e2011-08-16 23:24:13 +00002138 {
2139
Jim Ingham5a988412012-06-08 21:56:10 +00002140 size_t argc = command.GetArgumentCount();
Enrico Granata223383e2011-08-16 23:24:13 +00002141
2142 if (argc != 1)
2143 {
2144 result.AppendError ("'command script delete' requires one argument");
2145 result.SetStatus (eReturnStatusFailed);
2146 return false;
2147 }
2148
Jim Ingham5a988412012-06-08 21:56:10 +00002149 const char* cmd_name = command.GetArgumentAtIndex(0);
Enrico Granata223383e2011-08-16 23:24:13 +00002150
2151 if (cmd_name && *cmd_name && m_interpreter.HasUserCommands() && m_interpreter.UserCommandExists(cmd_name))
2152 {
2153 m_interpreter.RemoveUser(cmd_name);
2154 result.SetStatus (eReturnStatusSuccessFinishResult);
2155 }
2156 else
2157 {
2158 result.AppendErrorWithFormat ("command %s not found", cmd_name);
2159 result.SetStatus (eReturnStatusFailed);
2160 }
2161
2162 return result.Succeeded();
2163
2164 }
2165};
2166
2167#pragma mark CommandObjectMultiwordCommandsScript
2168
2169//-------------------------------------------------------------------------
2170// CommandObjectMultiwordCommandsScript
2171//-------------------------------------------------------------------------
2172
2173class CommandObjectMultiwordCommandsScript : public CommandObjectMultiword
2174{
2175public:
2176 CommandObjectMultiwordCommandsScript (CommandInterpreter &interpreter) :
2177 CommandObjectMultiword (interpreter,
2178 "command script",
2179 "A set of commands for managing or customizing script commands.",
2180 "command script <subcommand> [<subcommand-options>]")
2181 {
Greg Claytonb5472782015-01-09 19:08:20 +00002182 LoadSubCommand ("add", CommandObjectSP (new CommandObjectCommandsScriptAdd (interpreter)));
2183 LoadSubCommand ("delete", CommandObjectSP (new CommandObjectCommandsScriptDelete (interpreter)));
2184 LoadSubCommand ("clear", CommandObjectSP (new CommandObjectCommandsScriptClear (interpreter)));
Enrico Granata223383e2011-08-16 23:24:13 +00002185 LoadSubCommand ("list", CommandObjectSP (new CommandObjectCommandsScriptList (interpreter)));
Greg Claytonb5472782015-01-09 19:08:20 +00002186 LoadSubCommand ("import", CommandObjectSP (new CommandObjectCommandsScriptImport (interpreter)));
Enrico Granata223383e2011-08-16 23:24:13 +00002187 }
2188
2189 ~CommandObjectMultiwordCommandsScript ()
2190 {
2191 }
2192
2193};
2194
2195
Jim Inghamebc09c32010-07-07 03:36:20 +00002196#pragma mark CommandObjectMultiwordCommands
2197
2198//-------------------------------------------------------------------------
2199// CommandObjectMultiwordCommands
2200//-------------------------------------------------------------------------
2201
2202CommandObjectMultiwordCommands::CommandObjectMultiwordCommands (CommandInterpreter &interpreter) :
Greg Claytona7015092010-09-18 01:14:36 +00002203 CommandObjectMultiword (interpreter,
Greg Clayton0e5e5a72011-04-20 22:55:21 +00002204 "command",
Caroline Tice3f4c09c2010-09-07 22:38:08 +00002205 "A set of commands for managing or customizing the debugger commands.",
Greg Clayton0e5e5a72011-04-20 22:55:21 +00002206 "command <subcommand> [<subcommand-options>]")
Jim Inghamebc09c32010-07-07 03:36:20 +00002207{
Greg Claytona7015092010-09-18 01:14:36 +00002208 LoadSubCommand ("source", CommandObjectSP (new CommandObjectCommandsSource (interpreter)));
2209 LoadSubCommand ("alias", CommandObjectSP (new CommandObjectCommandsAlias (interpreter)));
2210 LoadSubCommand ("unalias", CommandObjectSP (new CommandObjectCommandsUnalias (interpreter)));
Greg Claytonb5472782015-01-09 19:08:20 +00002211 LoadSubCommand ("delete", CommandObjectSP (new CommandObjectCommandsDelete (interpreter)));
Greg Claytonde164aa2011-04-20 16:37:46 +00002212 LoadSubCommand ("regex", CommandObjectSP (new CommandObjectCommandsAddRegex (interpreter)));
Greg Claytonb5472782015-01-09 19:08:20 +00002213 LoadSubCommand ("history", CommandObjectSP (new CommandObjectCommandsHistory (interpreter)));
2214 LoadSubCommand ("script", CommandObjectSP (new CommandObjectMultiwordCommandsScript (interpreter)));
Jim Inghamebc09c32010-07-07 03:36:20 +00002215}
2216
2217CommandObjectMultiwordCommands::~CommandObjectMultiwordCommands ()
2218{
2219}
2220