blob: 779a4ab3831d7e882492a5526bafaf2f1192dea3 [file] [log] [blame]
Jim Ingham767af882010-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
10#include "CommandObjectCommands.h"
11
12// C Includes
13// C++ Includes
14// Other libraries and framework includes
Greg Clayton40e48242011-04-20 22:55:21 +000015#include "llvm/ADT/StringRef.h"
16
Jim Ingham767af882010-07-07 03:36:20 +000017// Project includes
Jim Ingham767af882010-07-07 03:36:20 +000018#include "lldb/Core/Debugger.h"
Greg Claytond12aeab2011-04-20 16:37:46 +000019#include "lldb/Core/InputReader.h"
20#include "lldb/Interpreter/Args.h"
Jim Ingham767af882010-07-07 03:36:20 +000021#include "lldb/Interpreter/CommandInterpreter.h"
Greg Claytond12aeab2011-04-20 16:37:46 +000022#include "lldb/Interpreter/CommandObjectRegexCommand.h"
Jim Ingham767af882010-07-07 03:36:20 +000023#include "lldb/Interpreter/CommandReturnObject.h"
24#include "lldb/Interpreter/Options.h"
25
26using namespace lldb;
27using namespace lldb_private;
28
Jim Ingham767af882010-07-07 03:36:20 +000029//-------------------------------------------------------------------------
30// CommandObjectCommandsSource
31//-------------------------------------------------------------------------
32
Jim Ingham6247dbe2011-07-12 03:12:18 +000033class CommandObjectCommandsHistory : public CommandObject
34{
35private:
36
37 class CommandOptions : public Options
38 {
39 public:
40
41 CommandOptions (CommandInterpreter &interpreter) :
42 Options (interpreter)
43 {
44 }
45
46 virtual
47 ~CommandOptions (){}
48
49 virtual Error
50 SetOptionValue (uint32_t option_idx, const char *option_arg)
51 {
52 Error error;
53 char short_option = (char) m_getopt_table[option_idx].val;
54 bool success;
55
56 switch (short_option)
57 {
58 case 'c':
59 m_end_idx = Args::StringToUInt32(option_arg, UINT_MAX, 0, &success);
60 if (!success)
61 error.SetErrorStringWithFormat("Invalid value for count: %s.\n", option_arg);
62 if (m_end_idx != 0)
63 m_end_idx--;
64 m_start_idx = 0;
65 break;
66 case 'e':
67 m_end_idx = Args::StringToUInt32(option_arg, 0, 0, &success);
68 if (!success)
69 error.SetErrorStringWithFormat("Invalid value for end index: %s.\n", option_arg);
70 break;
71 case 's':
72 m_start_idx = Args::StringToUInt32(option_arg, 0, 0, &success);
73 if (!success)
74 error.SetErrorStringWithFormat("Invalid value for start index: %s.\n", option_arg);
75 break;
76 default:
77 error.SetErrorStringWithFormat ("Unrecognized option '%c'.\n", short_option);
78 break;
79 }
80
81 return error;
82 }
83
84 void
85 OptionParsingStarting ()
86 {
87 m_start_idx = 0;
88 m_end_idx = UINT_MAX;
89 }
90
91 const OptionDefinition*
92 GetDefinitions ()
93 {
94 return g_option_table;
95 }
96
97 // Options table: Required for subclasses of Options.
98
99 static OptionDefinition g_option_table[];
100
101 // Instance variables to hold the values for command options.
102
103 uint32_t m_start_idx;
104 uint32_t m_end_idx;
105 };
106
107 CommandOptions m_options;
108
109 virtual Options *
110 GetOptions ()
111 {
112 return &m_options;
113 }
114
115public:
116 CommandObjectCommandsHistory(CommandInterpreter &interpreter) :
117 CommandObject (interpreter,
118 "command history",
119 "Dump the history of commands in this session.",
120 NULL),
121 m_options (interpreter)
122 {
123 }
124
125 ~CommandObjectCommandsHistory ()
126 {
127 }
128
129 bool
130 Execute
131 (
132 Args& args,
133 CommandReturnObject &result
134 )
135 {
136
137 m_interpreter.DumpHistory (result.GetOutputStream(),
138 m_options.m_start_idx,
139 m_options.m_end_idx);
140 return result.Succeeded();
141
142 }
143};
144
145OptionDefinition
146CommandObjectCommandsHistory::CommandOptions::g_option_table[] =
147{
148{ LLDB_OPT_SET_1, false, "count", 'c', required_argument, NULL, 0, eArgTypeUnsignedInteger, "How many history commands to print."},
149{ LLDB_OPT_SET_1, false, "start-index", 's', required_argument, NULL, 0, eArgTypeUnsignedInteger, "Index at which to start printing history commands."},
150{ LLDB_OPT_SET_1, false, "end-index", 'e', required_argument, NULL, 0, eArgTypeUnsignedInteger, "Index at which to stop printing history commands."},
151{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
152};
153
154
155//-------------------------------------------------------------------------
156// CommandObjectCommandsSource
157//-------------------------------------------------------------------------
158
Jim Ingham767af882010-07-07 03:36:20 +0000159class CommandObjectCommandsSource : public CommandObject
160{
Jim Ingham949d5ac2011-02-18 00:54:25 +0000161private:
162
163 class CommandOptions : public Options
164 {
165 public:
166
Greg Claytonf15996e2011-04-07 22:46:35 +0000167 CommandOptions (CommandInterpreter &interpreter) :
168 Options (interpreter)
169 {
170 }
Jim Ingham949d5ac2011-02-18 00:54:25 +0000171
172 virtual
173 ~CommandOptions (){}
174
175 virtual Error
Greg Clayton143fcc32011-04-13 00:18:08 +0000176 SetOptionValue (uint32_t option_idx, const char *option_arg)
Jim Ingham949d5ac2011-02-18 00:54:25 +0000177 {
178 Error error;
179 char short_option = (char) m_getopt_table[option_idx].val;
180 bool success;
181
182 switch (short_option)
183 {
184 case 'e':
185 m_stop_on_error = Args::StringToBoolean(option_arg, true, &success);
186 if (!success)
187 error.SetErrorStringWithFormat("Invalid value for stop-on-error: %s.\n", option_arg);
188 break;
189 case 'c':
190 m_stop_on_continue = Args::StringToBoolean(option_arg, true, &success);
191 if (!success)
192 error.SetErrorStringWithFormat("Invalid value for stop-on-continue: %s.\n", option_arg);
193 break;
194 default:
195 error.SetErrorStringWithFormat ("Unrecognized option '%c'.\n", short_option);
196 break;
197 }
198
199 return error;
200 }
201
202 void
Greg Clayton143fcc32011-04-13 00:18:08 +0000203 OptionParsingStarting ()
Jim Ingham949d5ac2011-02-18 00:54:25 +0000204 {
Jim Ingham949d5ac2011-02-18 00:54:25 +0000205 m_stop_on_error = true;
206 m_stop_on_continue = true;
207 }
208
Greg Claytonb3448432011-03-24 21:19:54 +0000209 const OptionDefinition*
Jim Ingham949d5ac2011-02-18 00:54:25 +0000210 GetDefinitions ()
211 {
212 return g_option_table;
213 }
214
215 // Options table: Required for subclasses of Options.
216
Greg Claytonb3448432011-03-24 21:19:54 +0000217 static OptionDefinition g_option_table[];
Jim Ingham949d5ac2011-02-18 00:54:25 +0000218
219 // Instance variables to hold the values for command options.
220
221 bool m_stop_on_error;
222 bool m_stop_on_continue;
223 };
224
Jim Ingham949d5ac2011-02-18 00:54:25 +0000225 CommandOptions m_options;
226
227 virtual Options *
228 GetOptions ()
229 {
230 return &m_options;
231 }
232
Jim Ingham767af882010-07-07 03:36:20 +0000233public:
Greg Clayton238c0a12010-09-18 01:14:36 +0000234 CommandObjectCommandsSource(CommandInterpreter &interpreter) :
235 CommandObject (interpreter,
Greg Clayton40e48242011-04-20 22:55:21 +0000236 "command source",
Greg Clayton238c0a12010-09-18 01:14:36 +0000237 "Read in debugger commands from the file <filename> and execute them.",
Greg Claytonf15996e2011-04-07 22:46:35 +0000238 NULL),
239 m_options (interpreter)
Jim Ingham767af882010-07-07 03:36:20 +0000240 {
Caroline Tice43b014a2010-10-04 22:28:36 +0000241 CommandArgumentEntry arg;
242 CommandArgumentData file_arg;
243
244 // Define the first (and only) variant of this arg.
245 file_arg.arg_type = eArgTypeFilename;
246 file_arg.arg_repetition = eArgRepeatPlain;
247
248 // There is only one variant this argument could be; put it into the argument entry.
249 arg.push_back (file_arg);
250
251 // Push the data for the first argument into the m_arguments vector.
252 m_arguments.push_back (arg);
Jim Ingham767af882010-07-07 03:36:20 +0000253 }
254
255 ~CommandObjectCommandsSource ()
256 {
257 }
258
259 bool
260 Execute
261 (
Jim Ingham767af882010-07-07 03:36:20 +0000262 Args& args,
263 CommandReturnObject &result
264 )
265 {
266 const int argc = args.GetArgumentCount();
267 if (argc == 1)
268 {
269 const char *filename = args.GetArgumentAtIndex(0);
Jim Ingham767af882010-07-07 03:36:20 +0000270
271 result.AppendMessageWithFormat ("Executing commands in '%s'.\n", filename);
272
Johnny Chena83ea882010-10-20 21:40:50 +0000273 FileSpec cmd_file (filename, true);
Jim Ingham949d5ac2011-02-18 00:54:25 +0000274 ExecutionContext *exe_ctx = NULL; // Just use the default context.
275 bool echo_commands = true;
276 bool print_results = true;
Jim Ingham767af882010-07-07 03:36:20 +0000277
Jim Ingham949d5ac2011-02-18 00:54:25 +0000278 m_interpreter.HandleCommandsFromFile (cmd_file,
279 exe_ctx,
280 m_options.m_stop_on_continue,
281 m_options.m_stop_on_error,
282 echo_commands,
283 print_results,
284 result);
Jim Ingham767af882010-07-07 03:36:20 +0000285 }
286 else
287 {
288 result.AppendErrorWithFormat("'%s' takes exactly one executable filename argument.\n", GetCommandName());
289 result.SetStatus (eReturnStatusFailed);
290 }
291 return result.Succeeded();
292
293 }
294};
295
Greg Claytonb3448432011-03-24 21:19:54 +0000296OptionDefinition
Jim Ingham949d5ac2011-02-18 00:54:25 +0000297CommandObjectCommandsSource::CommandOptions::g_option_table[] =
298{
299{ LLDB_OPT_SET_ALL, false, "stop-on-error", 'e', required_argument, NULL, 0, eArgTypeBoolean, "If true, stop executing commands on error."},
300{ LLDB_OPT_SET_ALL, false, "stop-on-continue", 'c', required_argument, NULL, 0, eArgTypeBoolean, "If true, stop executing commands on continue."},
301{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
302};
303
Jim Ingham767af882010-07-07 03:36:20 +0000304#pragma mark CommandObjectCommandsAlias
305//-------------------------------------------------------------------------
306// CommandObjectCommandsAlias
307//-------------------------------------------------------------------------
308
309class CommandObjectCommandsAlias : public CommandObject
310{
311public:
Greg Clayton238c0a12010-09-18 01:14:36 +0000312 CommandObjectCommandsAlias (CommandInterpreter &interpreter) :
313 CommandObject (interpreter,
Greg Clayton40e48242011-04-20 22:55:21 +0000314 "command alias",
Caroline Ticeabb507a2010-09-08 21:06:11 +0000315 "Allow users to define their own debugger command abbreviations.",
Caroline Tice43b014a2010-10-04 22:28:36 +0000316 NULL)
Jim Ingham767af882010-07-07 03:36:20 +0000317 {
318 SetHelpLong(
319 "'alias' allows the user to create a short-cut or abbreviation for long \n\
320 commands, multi-word commands, and commands that take particular options. \n\
321 Below are some simple examples of how one might use the 'alias' command: \n\
Caroline Tice31fbb642010-09-08 22:08:58 +0000322 \n 'commands alias sc script' // Creates the abbreviation 'sc' for the 'script' \n\
323 // command. \n\
324 'commands alias bp breakpoint' // Creates the abbreviation 'bp' for the 'breakpoint' \n\
325 // command. Since breakpoint commands are two-word \n\
326 // commands, the user will still need to enter the \n\
327 // second word after 'bp', e.g. 'bp enable' or \n\
328 // 'bp delete'. \n\
329 'commands alias bpl breakpoint list' // Creates the abbreviation 'bpl' for the \n\
330 // two-word command 'breakpoint list'. \n\
Jim Ingham767af882010-07-07 03:36:20 +0000331 \nAn alias can include some options for the command, with the values either \n\
332 filled in at the time the alias is created, or specified as positional \n\
333 arguments, to be filled in when the alias is invoked. The following example \n\
334 shows how to create aliases with options: \n\
335 \n\
Caroline Tice31fbb642010-09-08 22:08:58 +0000336 'commands alias bfl breakpoint set -f %1 -l %2' \n\
Jim Ingham767af882010-07-07 03:36:20 +0000337 \nThis creates the abbreviation 'bfl' (for break-file-line), with the -f and -l \n\
338 options already part of the alias. So if the user wants to set a breakpoint \n\
339 by file and line without explicitly having to use the -f and -l options, the \n\
340 user can now use 'bfl' instead. The '%1' and '%2' are positional placeholders \n\
341 for the actual arguments that will be passed when the alias command is used. \n\
342 The number in the placeholder refers to the position/order the actual value \n\
343 occupies when the alias is used. So all the occurrences of '%1' in the alias \n\
344 will be replaced with the first argument, all the occurrences of '%2' in the \n\
345 alias will be replaced with the second argument, and so on. This also allows \n\
346 actual arguments to be used multiple times within an alias (see 'process \n\
347 launch' example below). So in the 'bfl' case, the actual file value will be \n\
348 filled in with the first argument following 'bfl' and the actual line number \n\
349 value will be filled in with the second argument. The user would use this \n\
350 alias as follows: \n\
Caroline Tice31fbb642010-09-08 22:08:58 +0000351 \n (lldb) commands alias bfl breakpoint set -f %1 -l %2 \n\
Sean Callanana3aff732010-08-09 18:50:15 +0000352 <... some time later ...> \n\
Caroline Tice31fbb642010-09-08 22:08:58 +0000353 (lldb) bfl my-file.c 137 \n\
Jim Ingham767af882010-07-07 03:36:20 +0000354 \nThis would be the same as if the user had entered \n\
355 'breakpoint set -f my-file.c -l 137'. \n\
356 \nAnother example: \n\
Caroline Tice31fbb642010-09-08 22:08:58 +0000357 \n (lldb) commands alias pltty process launch -s -o %1 -e %1 \n\
358 (lldb) pltty /dev/tty0 \n\
Sean Callanana3aff732010-08-09 18:50:15 +0000359 // becomes 'process launch -s -o /dev/tty0 -e /dev/tty0' \n\
Jim Ingham767af882010-07-07 03:36:20 +0000360 \nIf the user always wanted to pass the same value to a particular option, the \n\
361 alias could be defined with that value directly in the alias as a constant, \n\
362 rather than using a positional placeholder: \n\
Sean Callanana3aff732010-08-09 18:50:15 +0000363 \n commands alias bl3 breakpoint set -f %1 -l 3 // Always sets a breakpoint on line \n\
364 // 3 of whatever file is indicated. \n");
Jim Ingham767af882010-07-07 03:36:20 +0000365
Caroline Tice43b014a2010-10-04 22:28:36 +0000366 CommandArgumentEntry arg1;
367 CommandArgumentEntry arg2;
368 CommandArgumentEntry arg3;
369 CommandArgumentData alias_arg;
370 CommandArgumentData cmd_arg;
371 CommandArgumentData options_arg;
372
373 // Define the first (and only) variant of this arg.
374 alias_arg.arg_type = eArgTypeAliasName;
375 alias_arg.arg_repetition = eArgRepeatPlain;
376
377 // There is only one variant this argument could be; put it into the argument entry.
378 arg1.push_back (alias_arg);
379
380 // Define the first (and only) variant of this arg.
381 cmd_arg.arg_type = eArgTypeCommandName;
382 cmd_arg.arg_repetition = eArgRepeatPlain;
383
384 // There is only one variant this argument could be; put it into the argument entry.
385 arg2.push_back (cmd_arg);
386
387 // Define the first (and only) variant of this arg.
388 options_arg.arg_type = eArgTypeAliasOptions;
389 options_arg.arg_repetition = eArgRepeatOptional;
390
391 // There is only one variant this argument could be; put it into the argument entry.
392 arg3.push_back (options_arg);
393
394 // Push the data for the first argument into the m_arguments vector.
395 m_arguments.push_back (arg1);
396 m_arguments.push_back (arg2);
397 m_arguments.push_back (arg3);
Jim Ingham767af882010-07-07 03:36:20 +0000398 }
399
400 ~CommandObjectCommandsAlias ()
401 {
402 }
403
Caroline Ticee0da7a52010-12-09 22:52:49 +0000404 bool
405 WantsRawCommandString ()
406 {
407 return true;
408 }
409
410 bool
411 ExecuteRawCommandString (const char *raw_command_line, CommandReturnObject &result)
412 {
413 Args args (raw_command_line);
414 std::string raw_command_string (raw_command_line);
415
416 size_t argc = args.GetArgumentCount();
417
418 if (argc < 2)
419 {
420 result.AppendError ("'alias' requires at least two arguments");
421 result.SetStatus (eReturnStatusFailed);
422 return false;
423 }
424
425 // Get the alias command.
426
427 const std::string alias_command = args.GetArgumentAtIndex (0);
428
429 // Strip the new alias name off 'raw_command_string' (leave it on args, which gets passed to 'Execute', which
430 // does the stripping itself.
431 size_t pos = raw_command_string.find (alias_command);
432 if (pos == 0)
433 {
434 raw_command_string = raw_command_string.substr (alias_command.size());
435 pos = raw_command_string.find_first_not_of (' ');
436 if ((pos != std::string::npos) && (pos > 0))
437 raw_command_string = raw_command_string.substr (pos);
438 }
439 else
440 {
441 result.AppendError ("Error parsing command string. No alias created.");
442 result.SetStatus (eReturnStatusFailed);
443 return false;
444 }
445
446
447 // Verify that the command is alias-able.
448 if (m_interpreter.CommandExists (alias_command.c_str()))
449 {
450 result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be redefined.\n",
451 alias_command.c_str());
452 result.SetStatus (eReturnStatusFailed);
453 return false;
454 }
455
456 // Get CommandObject that is being aliased. The command name is read from the front of raw_command_string.
457 // raw_command_string is returned with the name of the command object stripped off the front.
458 CommandObject *cmd_obj = m_interpreter.GetCommandObjectForCommand (raw_command_string);
459
460 if (!cmd_obj)
461 {
462 result.AppendErrorWithFormat ("Invalid command given to 'alias'. '%s' does not begin with a valid command."
463 " No alias created.", raw_command_string.c_str());
464 result.SetStatus (eReturnStatusFailed);
465 return false;
466 }
467 else if (!cmd_obj->WantsRawCommandString ())
468 {
469 // Note that args was initialized with the original command, and has not been updated to this point.
470 // Therefore can we pass it to the version of Execute that does not need/expect raw input in the alias.
471 return Execute (args, result);
472 }
473 else
474 {
475 // Verify & handle any options/arguments passed to the alias command
476
477 OptionArgVectorSP option_arg_vector_sp = OptionArgVectorSP (new OptionArgVector);
478 OptionArgVector *option_arg_vector = option_arg_vector_sp.get();
479
Caroline Tice5ddbe212011-05-06 21:37:15 +0000480 CommandObjectSP cmd_obj_sp = m_interpreter.GetCommandSPExact (cmd_obj->GetCommandName(), false);
481
482 if (!m_interpreter.ProcessAliasOptionsArgs (cmd_obj_sp, raw_command_string.c_str(), option_arg_vector_sp))
Caroline Ticee0da7a52010-12-09 22:52:49 +0000483 {
Caroline Tice5ddbe212011-05-06 21:37:15 +0000484 result.AppendError ("Unable to create requested alias.\n");
485 result.SetStatus (eReturnStatusFailed);
486 return false;
Caroline Ticee0da7a52010-12-09 22:52:49 +0000487 }
488
489 // Create the alias
490 if (m_interpreter.AliasExists (alias_command.c_str())
491 || m_interpreter.UserCommandExists (alias_command.c_str()))
492 {
493 OptionArgVectorSP temp_option_arg_sp (m_interpreter.GetAliasOptions (alias_command.c_str()));
494 if (temp_option_arg_sp.get())
495 {
496 if (option_arg_vector->size() == 0)
497 m_interpreter.RemoveAliasOptions (alias_command.c_str());
498 }
499 result.AppendWarningWithFormat ("Overwriting existing definition for '%s'.\n",
500 alias_command.c_str());
501 }
502
Caroline Tice56d2fc42010-12-14 18:51:39 +0000503 if (cmd_obj_sp)
504 {
505 m_interpreter.AddAlias (alias_command.c_str(), cmd_obj_sp);
506 if (option_arg_vector->size() > 0)
507 m_interpreter.AddOrReplaceAliasOptions (alias_command.c_str(), option_arg_vector_sp);
508 result.SetStatus (eReturnStatusSuccessFinishNoResult);
509 }
510 else
511 {
512 result.AppendError ("Unable to create requested alias.\n");
513 result.SetStatus (eReturnStatusFailed);
514 }
Caroline Ticee0da7a52010-12-09 22:52:49 +0000515 }
516 return result.Succeeded();
517 }
Jim Ingham767af882010-07-07 03:36:20 +0000518
519 bool
520 Execute
521 (
Jim Ingham767af882010-07-07 03:36:20 +0000522 Args& args,
523 CommandReturnObject &result
524 )
525 {
Caroline Tice8bb61f02010-09-21 23:25:40 +0000526 size_t argc = args.GetArgumentCount();
Jim Ingham767af882010-07-07 03:36:20 +0000527
528 if (argc < 2)
Greg Clayton54e7afa2010-07-09 20:39:50 +0000529 {
Jim Ingham767af882010-07-07 03:36:20 +0000530 result.AppendError ("'alias' requires at least two arguments");
531 result.SetStatus (eReturnStatusFailed);
532 return false;
Greg Clayton54e7afa2010-07-09 20:39:50 +0000533 }
Jim Ingham767af882010-07-07 03:36:20 +0000534
535 const std::string alias_command = args.GetArgumentAtIndex(0);
536 const std::string actual_command = args.GetArgumentAtIndex(1);
537
538 args.Shift(); // Shift the alias command word off the argument vector.
539 args.Shift(); // Shift the old command word off the argument vector.
540
541 // Verify that the command is alias'able, and get the appropriate command object.
542
Greg Clayton238c0a12010-09-18 01:14:36 +0000543 if (m_interpreter.CommandExists (alias_command.c_str()))
Jim Ingham767af882010-07-07 03:36:20 +0000544 {
545 result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be redefined.\n",
546 alias_command.c_str());
547 result.SetStatus (eReturnStatusFailed);
548 }
549 else
550 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000551 CommandObjectSP command_obj_sp(m_interpreter.GetCommandSPExact (actual_command.c_str(), true));
Jim Ingham767af882010-07-07 03:36:20 +0000552 CommandObjectSP subcommand_obj_sp;
553 bool use_subcommand = false;
554 if (command_obj_sp.get())
555 {
556 CommandObject *cmd_obj = command_obj_sp.get();
Greg Clayton54e7afa2010-07-09 20:39:50 +0000557 CommandObject *sub_cmd_obj = NULL;
Jim Ingham767af882010-07-07 03:36:20 +0000558 OptionArgVectorSP option_arg_vector_sp = OptionArgVectorSP (new OptionArgVector);
559 OptionArgVector *option_arg_vector = option_arg_vector_sp.get();
560
Caroline Ticee0da7a52010-12-09 22:52:49 +0000561 while (cmd_obj->IsMultiwordObject() && args.GetArgumentCount() > 0)
Jim Ingham767af882010-07-07 03:36:20 +0000562 {
563 if (argc >= 3)
564 {
565 const std::string sub_command = args.GetArgumentAtIndex(0);
566 assert (sub_command.length() != 0);
567 subcommand_obj_sp =
568 (((CommandObjectMultiword *) cmd_obj)->GetSubcommandSP (sub_command.c_str()));
569 if (subcommand_obj_sp.get())
570 {
571 sub_cmd_obj = subcommand_obj_sp.get();
572 use_subcommand = true;
573 args.Shift(); // Shift the sub_command word off the argument vector.
Caroline Ticee0da7a52010-12-09 22:52:49 +0000574 cmd_obj = sub_cmd_obj;
Jim Ingham767af882010-07-07 03:36:20 +0000575 }
576 else
577 {
Caroline Tice5d53b622010-11-02 19:00:04 +0000578 result.AppendErrorWithFormat("'%s' is not a valid sub-command of '%s'. "
579 "Unable to create alias.\n",
580 sub_command.c_str(), actual_command.c_str());
Jim Ingham767af882010-07-07 03:36:20 +0000581 result.SetStatus (eReturnStatusFailed);
582 return false;
583 }
584 }
585 }
586
587 // Verify & handle any options/arguments passed to the alias command
588
589 if (args.GetArgumentCount () > 0)
590 {
Caroline Tice5ddbe212011-05-06 21:37:15 +0000591 CommandObjectSP tmp_sp = m_interpreter.GetCommandSPExact (cmd_obj->GetCommandName(), false);
592 if (use_subcommand)
593 tmp_sp = m_interpreter.GetCommandSPExact (sub_cmd_obj->GetCommandName(), false);
594
595 std::string args_string;
596 args.GetCommandString (args_string);
597
598 if (!m_interpreter.ProcessAliasOptionsArgs (tmp_sp, args_string.c_str(), option_arg_vector_sp))
599 {
600 result.AppendError ("Unable to create requested alias.\n");
601 result.SetStatus (eReturnStatusFailed);
602 return false;
603 }
Jim Ingham767af882010-07-07 03:36:20 +0000604 }
605
606 // Create the alias.
607
Greg Clayton238c0a12010-09-18 01:14:36 +0000608 if (m_interpreter.AliasExists (alias_command.c_str())
609 || m_interpreter.UserCommandExists (alias_command.c_str()))
Jim Ingham767af882010-07-07 03:36:20 +0000610 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000611 OptionArgVectorSP tmp_option_arg_sp (m_interpreter.GetAliasOptions (alias_command.c_str()));
Jim Ingham767af882010-07-07 03:36:20 +0000612 if (tmp_option_arg_sp.get())
613 {
614 if (option_arg_vector->size() == 0)
Greg Clayton238c0a12010-09-18 01:14:36 +0000615 m_interpreter.RemoveAliasOptions (alias_command.c_str());
Jim Ingham767af882010-07-07 03:36:20 +0000616 }
617 result.AppendWarningWithFormat ("Overwriting existing definition for '%s'.\n",
618 alias_command.c_str());
619 }
620
621 if (use_subcommand)
Greg Clayton238c0a12010-09-18 01:14:36 +0000622 m_interpreter.AddAlias (alias_command.c_str(), subcommand_obj_sp);
Jim Ingham767af882010-07-07 03:36:20 +0000623 else
Greg Clayton238c0a12010-09-18 01:14:36 +0000624 m_interpreter.AddAlias (alias_command.c_str(), command_obj_sp);
Jim Ingham767af882010-07-07 03:36:20 +0000625 if (option_arg_vector->size() > 0)
Greg Clayton238c0a12010-09-18 01:14:36 +0000626 m_interpreter.AddOrReplaceAliasOptions (alias_command.c_str(), option_arg_vector_sp);
Jim Ingham767af882010-07-07 03:36:20 +0000627 result.SetStatus (eReturnStatusSuccessFinishNoResult);
628 }
629 else
630 {
631 result.AppendErrorWithFormat ("'%s' is not an existing command.\n", actual_command.c_str());
632 result.SetStatus (eReturnStatusFailed);
Caroline Ticee6866a32010-10-28 23:17:48 +0000633 return false;
Jim Ingham767af882010-07-07 03:36:20 +0000634 }
635 }
636
637 return result.Succeeded();
638 }
639};
640
641#pragma mark CommandObjectCommandsUnalias
642//-------------------------------------------------------------------------
643// CommandObjectCommandsUnalias
644//-------------------------------------------------------------------------
645
646class CommandObjectCommandsUnalias : public CommandObject
647{
648public:
Greg Clayton238c0a12010-09-18 01:14:36 +0000649 CommandObjectCommandsUnalias (CommandInterpreter &interpreter) :
650 CommandObject (interpreter,
Greg Clayton40e48242011-04-20 22:55:21 +0000651 "command unalias",
Caroline Tice146292c2010-09-12 04:56:10 +0000652 "Allow the user to remove/delete a user-defined command abbreviation.",
Caroline Tice43b014a2010-10-04 22:28:36 +0000653 NULL)
Jim Ingham767af882010-07-07 03:36:20 +0000654 {
Caroline Tice43b014a2010-10-04 22:28:36 +0000655 CommandArgumentEntry arg;
656 CommandArgumentData alias_arg;
657
658 // Define the first (and only) variant of this arg.
659 alias_arg.arg_type = eArgTypeAliasName;
660 alias_arg.arg_repetition = eArgRepeatPlain;
661
662 // There is only one variant this argument could be; put it into the argument entry.
663 arg.push_back (alias_arg);
664
665 // Push the data for the first argument into the m_arguments vector.
666 m_arguments.push_back (arg);
Jim Ingham767af882010-07-07 03:36:20 +0000667 }
668
669 ~CommandObjectCommandsUnalias()
670 {
671 }
672
673
674 bool
675 Execute
676 (
Jim Ingham767af882010-07-07 03:36:20 +0000677 Args& args,
678 CommandReturnObject &result
679 )
680 {
681 CommandObject::CommandMap::iterator pos;
682 CommandObject *cmd_obj;
683
684 if (args.GetArgumentCount() != 0)
685 {
686 const char *command_name = args.GetArgumentAtIndex(0);
Greg Clayton238c0a12010-09-18 01:14:36 +0000687 cmd_obj = m_interpreter.GetCommandObject(command_name);
Jim Ingham767af882010-07-07 03:36:20 +0000688 if (cmd_obj)
689 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000690 if (m_interpreter.CommandExists (command_name))
Jim Ingham767af882010-07-07 03:36:20 +0000691 {
692 result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be removed.\n",
693 command_name);
694 result.SetStatus (eReturnStatusFailed);
695 }
696 else
697 {
698
Greg Clayton238c0a12010-09-18 01:14:36 +0000699 if (m_interpreter.RemoveAlias (command_name) == false)
Jim Ingham767af882010-07-07 03:36:20 +0000700 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000701 if (m_interpreter.AliasExists (command_name))
Jim Ingham767af882010-07-07 03:36:20 +0000702 result.AppendErrorWithFormat ("Error occurred while attempting to unalias '%s'.\n",
703 command_name);
704 else
705 result.AppendErrorWithFormat ("'%s' is not an existing alias.\n", command_name);
706 result.SetStatus (eReturnStatusFailed);
707 }
708 else
709 result.SetStatus (eReturnStatusSuccessFinishNoResult);
710 }
711 }
712 else
713 {
714 result.AppendErrorWithFormat ("'%s' is not a known command.\nTry 'help' to see a "
715 "current list of commands.\n",
716 command_name);
717 result.SetStatus (eReturnStatusFailed);
718 }
719 }
720 else
721 {
722 result.AppendError ("must call 'unalias' with a valid alias");
723 result.SetStatus (eReturnStatusFailed);
724 }
725
726 return result.Succeeded();
727 }
728};
729
Greg Claytond12aeab2011-04-20 16:37:46 +0000730#pragma mark CommandObjectCommandsAddRegex
731//-------------------------------------------------------------------------
732// CommandObjectCommandsAddRegex
733//-------------------------------------------------------------------------
734
735class CommandObjectCommandsAddRegex : public CommandObject
736{
737public:
738 CommandObjectCommandsAddRegex (CommandInterpreter &interpreter) :
739 CommandObject (interpreter,
Greg Clayton40e48242011-04-20 22:55:21 +0000740 "command regex",
Greg Claytond12aeab2011-04-20 16:37:46 +0000741 "Allow the user to create a regular expression command.",
Greg Clayton40e48242011-04-20 22:55:21 +0000742 "command regex <cmd-name> [s/<regex>/<subst>/ ...]"),
Greg Claytond12aeab2011-04-20 16:37:46 +0000743 m_options (interpreter)
744 {
Greg Clayton40e48242011-04-20 22:55:21 +0000745 SetHelpLong(
746"This command allows the user to create powerful regular expression commands\n"
747"with substitutions. The regular expressions and substitutions are specified\n"
748"using the regular exression substitution format of:\n"
749"\n"
750" s/<regex>/<subst>/\n"
751"\n"
752"<regex> is a regular expression that can use parenthesis to capture regular\n"
753"expression input and substitute the captured matches in the output using %1\n"
754"for the first match, %2 for the second, and so on.\n"
755"\n"
756"The regular expressions can all be specified on the command line if more than\n"
757"one argument is provided. If just the command name is provided on the command\n"
758"line, then the regular expressions and substitutions can be entered on separate\n"
759" lines, followed by an empty line to terminate the command definition.\n"
760"\n"
761"EXAMPLES\n"
762"\n"
763"The following example with define a regular expression command named 'f' that\n"
764"will call 'finish' if there are no arguments, or 'frame select <frame-idx>' if\n"
765"a number follows 'f':\n"
766"(lldb) command regex f s/^$/finish/ 's/([0-9]+)/frame select %1/'\n"
767 );
Greg Claytond12aeab2011-04-20 16:37:46 +0000768 }
769
770 ~CommandObjectCommandsAddRegex()
771 {
772 }
773
774
775 bool
776 Execute (Args& args, CommandReturnObject &result)
777 {
Greg Clayton40e48242011-04-20 22:55:21 +0000778 const size_t argc = args.GetArgumentCount();
779 if (argc == 0)
Greg Claytond12aeab2011-04-20 16:37:46 +0000780 {
Greg Clayton40e48242011-04-20 22:55:21 +0000781 result.AppendError ("usage: 'commands regex <command-name> [s/<regex1>/<subst1>/ s/<regex2>/<subst2>/ ...]'\n");
782 result.SetStatus (eReturnStatusFailed);
783 }
784 else
785 {
786 Error error;
Greg Claytond12aeab2011-04-20 16:37:46 +0000787 const char *name = args.GetArgumentAtIndex(0);
Greg Claytond12aeab2011-04-20 16:37:46 +0000788 m_regex_cmd_ap.reset (new CommandObjectRegexCommand (m_interpreter,
789 name,
790 m_options.GetHelp (),
791 m_options.GetSyntax (),
792 10));
Greg Clayton40e48242011-04-20 22:55:21 +0000793
794 if (argc == 1)
Greg Claytond12aeab2011-04-20 16:37:46 +0000795 {
Greg Clayton40e48242011-04-20 22:55:21 +0000796 InputReaderSP reader_sp (new InputReader(m_interpreter.GetDebugger()));
797 if (reader_sp)
798 {
799 error =reader_sp->Initialize (CommandObjectCommandsAddRegex::InputReaderCallback,
Greg Claytond12aeab2011-04-20 16:37:46 +0000800 this, // baton
801 eInputReaderGranularityLine, // token size, to pass to callback function
Greg Clayton40e48242011-04-20 22:55:21 +0000802 NULL, // end token
Greg Claytond12aeab2011-04-20 16:37:46 +0000803 "> ", // prompt
Greg Clayton40e48242011-04-20 22:55:21 +0000804 true); // echo input
805 if (error.Success())
806 {
807 m_interpreter.GetDebugger().PushInputReader (reader_sp);
808 result.SetStatus (eReturnStatusSuccessFinishNoResult);
809 return true;
810 }
Greg Claytond12aeab2011-04-20 16:37:46 +0000811 }
812 }
Greg Clayton40e48242011-04-20 22:55:21 +0000813 else
814 {
815 for (size_t arg_idx = 1; arg_idx < argc; ++arg_idx)
816 {
817 llvm::StringRef arg_strref (args.GetArgumentAtIndex(arg_idx));
818 error = AppendRegexSubstitution (arg_strref);
819 if (error.Fail())
820 break;
821 }
822
823 if (error.Success())
824 {
825 AddRegexCommandToInterpreter();
826 }
827 }
828 if (error.Fail())
829 {
830 result.AppendError (error.AsCString());
831 result.SetStatus (eReturnStatusFailed);
832 }
Greg Claytond12aeab2011-04-20 16:37:46 +0000833 }
Greg Clayton40e48242011-04-20 22:55:21 +0000834
Greg Claytond12aeab2011-04-20 16:37:46 +0000835 return result.Succeeded();
836 }
837
Greg Clayton40e48242011-04-20 22:55:21 +0000838 Error
839 AppendRegexSubstitution (const llvm::StringRef &regex_sed)
Greg Claytond12aeab2011-04-20 16:37:46 +0000840 {
Greg Clayton40e48242011-04-20 22:55:21 +0000841 Error error;
842
843 if (m_regex_cmd_ap.get() == NULL)
Greg Claytond12aeab2011-04-20 16:37:46 +0000844 {
Greg Clayton40e48242011-04-20 22:55:21 +0000845 error.SetErrorStringWithFormat("invalid regular expression command object for: '%.*s'",
846 (int)regex_sed.size(),
847 regex_sed.data());
848 return error;
Greg Claytond12aeab2011-04-20 16:37:46 +0000849 }
Greg Clayton40e48242011-04-20 22:55:21 +0000850
851 size_t regex_sed_size = regex_sed.size();
852
853 if (regex_sed_size <= 1)
854 {
855 error.SetErrorStringWithFormat("regular expression substitution string is too short: '%.*s'",
856 (int)regex_sed.size(),
857 regex_sed.data());
858 return error;
859 }
860
861 if (regex_sed[0] != 's')
862 {
863 error.SetErrorStringWithFormat("regular expression substitution string doesn't start with 's': '%.*s'",
864 (int)regex_sed.size(),
865 regex_sed.data());
866 return error;
867 }
868 const size_t first_separator_char_pos = 1;
869 // use the char that follows 's' as the regex separator character
870 // so we can have "s/<regex>/<subst>/" or "s|<regex>|<subst>|"
871 const char separator_char = regex_sed[first_separator_char_pos];
872 const size_t second_separator_char_pos = regex_sed.find (separator_char, first_separator_char_pos + 1);
873
874 if (second_separator_char_pos == std::string::npos)
875 {
876 error.SetErrorStringWithFormat("missing second '%c' separator char after '%.*s'",
877 separator_char,
878 (int)(regex_sed.size() - first_separator_char_pos - 1),
879 regex_sed.data() + (first_separator_char_pos + 1));
880 return error;
881 }
882
883 const size_t third_separator_char_pos = regex_sed.find (separator_char, second_separator_char_pos + 1);
884
885 if (third_separator_char_pos == std::string::npos)
886 {
887 error.SetErrorStringWithFormat("missing third '%c' separator char after '%.*s'",
888 separator_char,
889 (int)(regex_sed.size() - second_separator_char_pos - 1),
890 regex_sed.data() + (second_separator_char_pos + 1));
891 return error;
892 }
893
894 if (third_separator_char_pos != regex_sed_size - 1)
895 {
896 // Make sure that everything that follows the last regex
897 // separator char
898 if (regex_sed.find_first_not_of("\t\n\v\f\r ", third_separator_char_pos + 1) != std::string::npos)
899 {
900 error.SetErrorStringWithFormat("extra data found after the '%.*s' regular expression substitution string: '%.*s'",
901 (int)third_separator_char_pos + 1,
902 regex_sed.data(),
903 (int)(regex_sed.size() - third_separator_char_pos - 1),
904 regex_sed.data() + (third_separator_char_pos + 1));
905 return error;
906 }
907
908 }
909 else if (first_separator_char_pos + 1 == second_separator_char_pos)
910 {
911 error.SetErrorStringWithFormat("<regex> can't be empty in 's%c<regex>%c<subst>%c' string: '%.*s'",
912 separator_char,
913 separator_char,
914 separator_char,
915 (int)regex_sed.size(),
916 regex_sed.data());
917 return error;
918 }
919 else if (second_separator_char_pos + 1 == third_separator_char_pos)
920 {
921 error.SetErrorStringWithFormat("<subst> can't be empty in 's%c<regex>%c<subst>%c' string: '%.*s'",
922 separator_char,
923 separator_char,
924 separator_char,
925 (int)regex_sed.size(),
926 regex_sed.data());
927 return error;
928 }
929 std::string regex(regex_sed.substr(first_separator_char_pos + 1, second_separator_char_pos - first_separator_char_pos - 1));
930 std::string subst(regex_sed.substr(second_separator_char_pos + 1, third_separator_char_pos - second_separator_char_pos - 1));
931 m_regex_cmd_ap->AddRegexCommand (regex.c_str(),
932 subst.c_str());
933 return error;
Greg Claytond12aeab2011-04-20 16:37:46 +0000934 }
935
936 void
Greg Clayton40e48242011-04-20 22:55:21 +0000937 AddRegexCommandToInterpreter()
Greg Claytond12aeab2011-04-20 16:37:46 +0000938 {
939 if (m_regex_cmd_ap.get())
940 {
941 if (m_regex_cmd_ap->HasRegexEntries())
942 {
943 CommandObjectSP cmd_sp (m_regex_cmd_ap.release());
944 m_interpreter.AddCommand(cmd_sp->GetCommandName(), cmd_sp, true);
945 }
946 }
947 }
948
Greg Clayton40e48242011-04-20 22:55:21 +0000949 void
950 InputReaderDidCancel()
951 {
952 m_regex_cmd_ap.reset();
953 }
954
Greg Claytond12aeab2011-04-20 16:37:46 +0000955 static size_t
956 InputReaderCallback (void *baton,
957 InputReader &reader,
958 lldb::InputReaderAction notification,
959 const char *bytes,
960 size_t bytes_len);
961private:
962 std::auto_ptr<CommandObjectRegexCommand> m_regex_cmd_ap;
963
964 class CommandOptions : public Options
965 {
966 public:
967
968 CommandOptions (CommandInterpreter &interpreter) :
969 Options (interpreter)
970 {
971 }
972
973 virtual
974 ~CommandOptions (){}
975
976 virtual Error
977 SetOptionValue (uint32_t option_idx, const char *option_arg)
978 {
979 Error error;
980 char short_option = (char) m_getopt_table[option_idx].val;
981
982 switch (short_option)
983 {
984 case 'h':
985 m_help.assign (option_arg);
986 break;
987 case 's':
988 m_syntax.assign (option_arg);
989 break;
990
991 default:
992 error.SetErrorStringWithFormat ("Unrecognized option '%c'.\n", short_option);
993 break;
994 }
995
996 return error;
997 }
998
999 void
1000 OptionParsingStarting ()
1001 {
1002 m_help.clear();
1003 m_syntax.clear();
1004 }
1005
1006 const OptionDefinition*
1007 GetDefinitions ()
1008 {
1009 return g_option_table;
1010 }
1011
1012 // Options table: Required for subclasses of Options.
1013
1014 static OptionDefinition g_option_table[];
1015
1016 const char *
1017 GetHelp ()
1018 {
1019 if (m_help.empty())
1020 return NULL;
1021 return m_help.c_str();
1022 }
1023 const char *
1024 GetSyntax ()
1025 {
1026 if (m_syntax.empty())
1027 return NULL;
1028 return m_syntax.c_str();
1029 }
1030 // Instance variables to hold the values for command options.
1031 protected:
1032 std::string m_help;
1033 std::string m_syntax;
1034 };
1035
1036 CommandOptions m_options;
1037
1038 virtual Options *
1039 GetOptions ()
1040 {
1041 return &m_options;
1042 }
1043
1044};
1045
1046size_t
1047CommandObjectCommandsAddRegex::InputReaderCallback (void *baton,
1048 InputReader &reader,
1049 lldb::InputReaderAction notification,
1050 const char *bytes,
1051 size_t bytes_len)
1052{
1053 CommandObjectCommandsAddRegex *add_regex_cmd = (CommandObjectCommandsAddRegex *) baton;
Caroline Tice892fadd2011-06-16 16:27:19 +00001054 bool batch_mode = reader.GetDebugger().GetCommandInterpreter().GetBatchCommandMode();
Greg Claytond12aeab2011-04-20 16:37:46 +00001055
1056 switch (notification)
1057 {
1058 case eInputReaderActivate:
Caroline Tice892fadd2011-06-16 16:27:19 +00001059 if (!batch_mode)
Caroline Tice2b5e4e62011-06-15 19:35:17 +00001060 {
1061 StreamSP out_stream = reader.GetDebugger().GetAsyncOutputStream ();
1062 out_stream->Printf("%s\n", "Enter regular expressions in the form 's/<regex>/<subst>/' and terminate with an empty line:");
1063 out_stream->Flush();
1064 }
Greg Claytond12aeab2011-04-20 16:37:46 +00001065 break;
1066 case eInputReaderReactivate:
1067 break;
1068
1069 case eInputReaderDeactivate:
1070 break;
Caroline Tice4a348082011-05-02 20:41:46 +00001071
1072 case eInputReaderAsynchronousOutputWritten:
1073 break;
1074
Greg Claytond12aeab2011-04-20 16:37:46 +00001075 case eInputReaderGotToken:
Greg Clayton40e48242011-04-20 22:55:21 +00001076 while (bytes_len > 0 && (bytes[bytes_len-1] == '\r' || bytes[bytes_len-1] == '\n'))
1077 --bytes_len;
Greg Claytond12aeab2011-04-20 16:37:46 +00001078 if (bytes_len == 0)
1079 reader.SetIsDone(true);
1080 else if (bytes)
1081 {
Greg Clayton40e48242011-04-20 22:55:21 +00001082 llvm::StringRef bytes_strref (bytes, bytes_len);
1083 Error error (add_regex_cmd->AppendRegexSubstitution (bytes_strref));
1084 if (error.Fail())
Greg Claytond12aeab2011-04-20 16:37:46 +00001085 {
Caroline Tice892fadd2011-06-16 16:27:19 +00001086 if (!batch_mode)
1087 {
1088 StreamSP out_stream = reader.GetDebugger().GetAsyncOutputStream();
1089 out_stream->Printf("error: %s\n", error.AsCString());
1090 out_stream->Flush();
1091 }
Greg Clayton40e48242011-04-20 22:55:21 +00001092 add_regex_cmd->InputReaderDidCancel ();
1093 reader.SetIsDone (true);
Greg Claytond12aeab2011-04-20 16:37:46 +00001094 }
1095 }
1096 break;
1097
1098 case eInputReaderInterrupt:
Caroline Tice2b5e4e62011-06-15 19:35:17 +00001099 {
1100 reader.SetIsDone (true);
Caroline Tice892fadd2011-06-16 16:27:19 +00001101 if (!batch_mode)
1102 {
1103 StreamSP out_stream = reader.GetDebugger().GetAsyncOutputStream();
1104 out_stream->PutCString("Regular expression command creations was cancelled.\n");
1105 out_stream->Flush();
1106 }
Caroline Tice2b5e4e62011-06-15 19:35:17 +00001107 add_regex_cmd->InputReaderDidCancel ();
1108 }
Greg Claytond12aeab2011-04-20 16:37:46 +00001109 break;
1110
1111 case eInputReaderEndOfFile:
1112 reader.SetIsDone (true);
1113 break;
1114
1115 case eInputReaderDone:
Greg Clayton40e48242011-04-20 22:55:21 +00001116 add_regex_cmd->AddRegexCommandToInterpreter();
Greg Claytond12aeab2011-04-20 16:37:46 +00001117 break;
1118 }
1119
1120 return bytes_len;
1121}
1122
1123
1124OptionDefinition
1125CommandObjectCommandsAddRegex::CommandOptions::g_option_table[] =
1126{
Greg Clayton40e48242011-04-20 22:55:21 +00001127{ LLDB_OPT_SET_1, false, "help" , 'h', required_argument, NULL, 0, eArgTypeNone, "The help text to display for this command."},
Greg Claytond12aeab2011-04-20 16:37:46 +00001128{ LLDB_OPT_SET_1, false, "syntax", 's', required_argument, NULL, 0, eArgTypeNone, "A syntax string showing the typical usage syntax."},
Greg Clayton40e48242011-04-20 22:55:21 +00001129{ 0 , false, NULL , 0 , 0 , NULL, 0, eArgTypeNone, NULL }
Greg Claytond12aeab2011-04-20 16:37:46 +00001130};
1131
1132
Jim Ingham767af882010-07-07 03:36:20 +00001133#pragma mark CommandObjectMultiwordCommands
1134
1135//-------------------------------------------------------------------------
1136// CommandObjectMultiwordCommands
1137//-------------------------------------------------------------------------
1138
1139CommandObjectMultiwordCommands::CommandObjectMultiwordCommands (CommandInterpreter &interpreter) :
Greg Clayton238c0a12010-09-18 01:14:36 +00001140 CommandObjectMultiword (interpreter,
Greg Clayton40e48242011-04-20 22:55:21 +00001141 "command",
Caroline Ticec1ad82e2010-09-07 22:38:08 +00001142 "A set of commands for managing or customizing the debugger commands.",
Greg Clayton40e48242011-04-20 22:55:21 +00001143 "command <subcommand> [<subcommand-options>]")
Jim Ingham767af882010-07-07 03:36:20 +00001144{
Greg Clayton238c0a12010-09-18 01:14:36 +00001145 LoadSubCommand ("source", CommandObjectSP (new CommandObjectCommandsSource (interpreter)));
1146 LoadSubCommand ("alias", CommandObjectSP (new CommandObjectCommandsAlias (interpreter)));
1147 LoadSubCommand ("unalias", CommandObjectSP (new CommandObjectCommandsUnalias (interpreter)));
Greg Claytond12aeab2011-04-20 16:37:46 +00001148 LoadSubCommand ("regex", CommandObjectSP (new CommandObjectCommandsAddRegex (interpreter)));
Jim Ingham6247dbe2011-07-12 03:12:18 +00001149 LoadSubCommand ("history", CommandObjectSP (new CommandObjectCommandsHistory (interpreter)));
Jim Ingham767af882010-07-07 03:36:20 +00001150}
1151
1152CommandObjectMultiwordCommands::~CommandObjectMultiwordCommands ()
1153{
1154}
1155