blob: 9230aea8ba139c439410d0c025a31543727ef06e [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
15// Project includes
16#include "lldb/Interpreter/Args.h"
17#include "lldb/Core/Debugger.h"
18#include "lldb/Interpreter/CommandInterpreter.h"
19#include "lldb/Interpreter/CommandReturnObject.h"
20#include "lldb/Interpreter/Options.h"
21
22using namespace lldb;
23using namespace lldb_private;
24
Jim Ingham767af882010-07-07 03:36:20 +000025//-------------------------------------------------------------------------
26// CommandObjectCommandsSource
27//-------------------------------------------------------------------------
28
29class CommandObjectCommandsSource : public CommandObject
30{
Jim Ingham949d5ac2011-02-18 00:54:25 +000031private:
32
33 class CommandOptions : public Options
34 {
35 public:
36
37 CommandOptions (){}
38
39 virtual
40 ~CommandOptions (){}
41
42 virtual Error
43 SetOptionValue (int option_idx, const char *option_arg)
44 {
45 Error error;
46 char short_option = (char) m_getopt_table[option_idx].val;
47 bool success;
48
49 switch (short_option)
50 {
51 case 'e':
52 m_stop_on_error = Args::StringToBoolean(option_arg, true, &success);
53 if (!success)
54 error.SetErrorStringWithFormat("Invalid value for stop-on-error: %s.\n", option_arg);
55 break;
56 case 'c':
57 m_stop_on_continue = Args::StringToBoolean(option_arg, true, &success);
58 if (!success)
59 error.SetErrorStringWithFormat("Invalid value for stop-on-continue: %s.\n", option_arg);
60 break;
61 default:
62 error.SetErrorStringWithFormat ("Unrecognized option '%c'.\n", short_option);
63 break;
64 }
65
66 return error;
67 }
68
69 void
70 ResetOptionValues ()
71 {
72 Options::ResetOptionValues();
73
74 m_stop_on_error = true;
75 m_stop_on_continue = true;
76 }
77
78 const lldb::OptionDefinition*
79 GetDefinitions ()
80 {
81 return g_option_table;
82 }
83
84 // Options table: Required for subclasses of Options.
85
86 static lldb::OptionDefinition g_option_table[];
87
88 // Instance variables to hold the values for command options.
89
90 bool m_stop_on_error;
91 bool m_stop_on_continue;
92 };
93
94 // Options table: Required for subclasses of Options.
95
96 static lldb::OptionDefinition g_option_table[];
97
98 CommandOptions m_options;
99
100 virtual Options *
101 GetOptions ()
102 {
103 return &m_options;
104 }
105
Jim Ingham767af882010-07-07 03:36:20 +0000106public:
Greg Clayton238c0a12010-09-18 01:14:36 +0000107 CommandObjectCommandsSource(CommandInterpreter &interpreter) :
108 CommandObject (interpreter,
109 "commands source",
110 "Read in debugger commands from the file <filename> and execute them.",
Caroline Tice43b014a2010-10-04 22:28:36 +0000111 NULL)
Jim Ingham767af882010-07-07 03:36:20 +0000112 {
Caroline Tice43b014a2010-10-04 22:28:36 +0000113 CommandArgumentEntry arg;
114 CommandArgumentData file_arg;
115
116 // Define the first (and only) variant of this arg.
117 file_arg.arg_type = eArgTypeFilename;
118 file_arg.arg_repetition = eArgRepeatPlain;
119
120 // There is only one variant this argument could be; put it into the argument entry.
121 arg.push_back (file_arg);
122
123 // Push the data for the first argument into the m_arguments vector.
124 m_arguments.push_back (arg);
Jim Ingham767af882010-07-07 03:36:20 +0000125 }
126
127 ~CommandObjectCommandsSource ()
128 {
129 }
130
131 bool
132 Execute
133 (
Jim Ingham767af882010-07-07 03:36:20 +0000134 Args& args,
135 CommandReturnObject &result
136 )
137 {
138 const int argc = args.GetArgumentCount();
139 if (argc == 1)
140 {
141 const char *filename = args.GetArgumentAtIndex(0);
Jim Ingham767af882010-07-07 03:36:20 +0000142
143 result.AppendMessageWithFormat ("Executing commands in '%s'.\n", filename);
144
Johnny Chena83ea882010-10-20 21:40:50 +0000145 FileSpec cmd_file (filename, true);
Jim Ingham949d5ac2011-02-18 00:54:25 +0000146 ExecutionContext *exe_ctx = NULL; // Just use the default context.
147 bool echo_commands = true;
148 bool print_results = true;
Jim Ingham767af882010-07-07 03:36:20 +0000149
Jim Ingham949d5ac2011-02-18 00:54:25 +0000150 m_interpreter.HandleCommandsFromFile (cmd_file,
151 exe_ctx,
152 m_options.m_stop_on_continue,
153 m_options.m_stop_on_error,
154 echo_commands,
155 print_results,
156 result);
Jim Ingham767af882010-07-07 03:36:20 +0000157 }
158 else
159 {
160 result.AppendErrorWithFormat("'%s' takes exactly one executable filename argument.\n", GetCommandName());
161 result.SetStatus (eReturnStatusFailed);
162 }
163 return result.Succeeded();
164
165 }
166};
167
Jim Ingham949d5ac2011-02-18 00:54:25 +0000168lldb::OptionDefinition
169CommandObjectCommandsSource::CommandOptions::g_option_table[] =
170{
171{ LLDB_OPT_SET_ALL, false, "stop-on-error", 'e', required_argument, NULL, 0, eArgTypeBoolean, "If true, stop executing commands on error."},
172{ LLDB_OPT_SET_ALL, false, "stop-on-continue", 'c', required_argument, NULL, 0, eArgTypeBoolean, "If true, stop executing commands on continue."},
173{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
174};
175
Jim Ingham767af882010-07-07 03:36:20 +0000176#pragma mark CommandObjectCommandsAlias
177//-------------------------------------------------------------------------
178// CommandObjectCommandsAlias
179//-------------------------------------------------------------------------
180
181class CommandObjectCommandsAlias : public CommandObject
182{
183public:
Greg Clayton238c0a12010-09-18 01:14:36 +0000184 CommandObjectCommandsAlias (CommandInterpreter &interpreter) :
185 CommandObject (interpreter,
186 "commands alias",
Caroline Ticeabb507a2010-09-08 21:06:11 +0000187 "Allow users to define their own debugger command abbreviations.",
Caroline Tice43b014a2010-10-04 22:28:36 +0000188 NULL)
Jim Ingham767af882010-07-07 03:36:20 +0000189 {
190 SetHelpLong(
191 "'alias' allows the user to create a short-cut or abbreviation for long \n\
192 commands, multi-word commands, and commands that take particular options. \n\
193 Below are some simple examples of how one might use the 'alias' command: \n\
Caroline Tice31fbb642010-09-08 22:08:58 +0000194 \n 'commands alias sc script' // Creates the abbreviation 'sc' for the 'script' \n\
195 // command. \n\
196 'commands alias bp breakpoint' // Creates the abbreviation 'bp' for the 'breakpoint' \n\
197 // command. Since breakpoint commands are two-word \n\
198 // commands, the user will still need to enter the \n\
199 // second word after 'bp', e.g. 'bp enable' or \n\
200 // 'bp delete'. \n\
201 'commands alias bpl breakpoint list' // Creates the abbreviation 'bpl' for the \n\
202 // two-word command 'breakpoint list'. \n\
Jim Ingham767af882010-07-07 03:36:20 +0000203 \nAn alias can include some options for the command, with the values either \n\
204 filled in at the time the alias is created, or specified as positional \n\
205 arguments, to be filled in when the alias is invoked. The following example \n\
206 shows how to create aliases with options: \n\
207 \n\
Caroline Tice31fbb642010-09-08 22:08:58 +0000208 'commands alias bfl breakpoint set -f %1 -l %2' \n\
Jim Ingham767af882010-07-07 03:36:20 +0000209 \nThis creates the abbreviation 'bfl' (for break-file-line), with the -f and -l \n\
210 options already part of the alias. So if the user wants to set a breakpoint \n\
211 by file and line without explicitly having to use the -f and -l options, the \n\
212 user can now use 'bfl' instead. The '%1' and '%2' are positional placeholders \n\
213 for the actual arguments that will be passed when the alias command is used. \n\
214 The number in the placeholder refers to the position/order the actual value \n\
215 occupies when the alias is used. So all the occurrences of '%1' in the alias \n\
216 will be replaced with the first argument, all the occurrences of '%2' in the \n\
217 alias will be replaced with the second argument, and so on. This also allows \n\
218 actual arguments to be used multiple times within an alias (see 'process \n\
219 launch' example below). So in the 'bfl' case, the actual file value will be \n\
220 filled in with the first argument following 'bfl' and the actual line number \n\
221 value will be filled in with the second argument. The user would use this \n\
222 alias as follows: \n\
Caroline Tice31fbb642010-09-08 22:08:58 +0000223 \n (lldb) commands alias bfl breakpoint set -f %1 -l %2 \n\
Sean Callanana3aff732010-08-09 18:50:15 +0000224 <... some time later ...> \n\
Caroline Tice31fbb642010-09-08 22:08:58 +0000225 (lldb) bfl my-file.c 137 \n\
Jim Ingham767af882010-07-07 03:36:20 +0000226 \nThis would be the same as if the user had entered \n\
227 'breakpoint set -f my-file.c -l 137'. \n\
228 \nAnother example: \n\
Caroline Tice31fbb642010-09-08 22:08:58 +0000229 \n (lldb) commands alias pltty process launch -s -o %1 -e %1 \n\
230 (lldb) pltty /dev/tty0 \n\
Sean Callanana3aff732010-08-09 18:50:15 +0000231 // becomes 'process launch -s -o /dev/tty0 -e /dev/tty0' \n\
Jim Ingham767af882010-07-07 03:36:20 +0000232 \nIf the user always wanted to pass the same value to a particular option, the \n\
233 alias could be defined with that value directly in the alias as a constant, \n\
234 rather than using a positional placeholder: \n\
Sean Callanana3aff732010-08-09 18:50:15 +0000235 \n commands alias bl3 breakpoint set -f %1 -l 3 // Always sets a breakpoint on line \n\
236 // 3 of whatever file is indicated. \n");
Jim Ingham767af882010-07-07 03:36:20 +0000237
Caroline Tice43b014a2010-10-04 22:28:36 +0000238 CommandArgumentEntry arg1;
239 CommandArgumentEntry arg2;
240 CommandArgumentEntry arg3;
241 CommandArgumentData alias_arg;
242 CommandArgumentData cmd_arg;
243 CommandArgumentData options_arg;
244
245 // Define the first (and only) variant of this arg.
246 alias_arg.arg_type = eArgTypeAliasName;
247 alias_arg.arg_repetition = eArgRepeatPlain;
248
249 // There is only one variant this argument could be; put it into the argument entry.
250 arg1.push_back (alias_arg);
251
252 // Define the first (and only) variant of this arg.
253 cmd_arg.arg_type = eArgTypeCommandName;
254 cmd_arg.arg_repetition = eArgRepeatPlain;
255
256 // There is only one variant this argument could be; put it into the argument entry.
257 arg2.push_back (cmd_arg);
258
259 // Define the first (and only) variant of this arg.
260 options_arg.arg_type = eArgTypeAliasOptions;
261 options_arg.arg_repetition = eArgRepeatOptional;
262
263 // There is only one variant this argument could be; put it into the argument entry.
264 arg3.push_back (options_arg);
265
266 // Push the data for the first argument into the m_arguments vector.
267 m_arguments.push_back (arg1);
268 m_arguments.push_back (arg2);
269 m_arguments.push_back (arg3);
Jim Ingham767af882010-07-07 03:36:20 +0000270 }
271
272 ~CommandObjectCommandsAlias ()
273 {
274 }
275
Caroline Ticee0da7a52010-12-09 22:52:49 +0000276 bool
277 WantsRawCommandString ()
278 {
279 return true;
280 }
281
282 bool
283 ExecuteRawCommandString (const char *raw_command_line, CommandReturnObject &result)
284 {
285 Args args (raw_command_line);
286 std::string raw_command_string (raw_command_line);
287
288 size_t argc = args.GetArgumentCount();
289
290 if (argc < 2)
291 {
292 result.AppendError ("'alias' requires at least two arguments");
293 result.SetStatus (eReturnStatusFailed);
294 return false;
295 }
296
297 // Get the alias command.
298
299 const std::string alias_command = args.GetArgumentAtIndex (0);
300
301 // Strip the new alias name off 'raw_command_string' (leave it on args, which gets passed to 'Execute', which
302 // does the stripping itself.
303 size_t pos = raw_command_string.find (alias_command);
304 if (pos == 0)
305 {
306 raw_command_string = raw_command_string.substr (alias_command.size());
307 pos = raw_command_string.find_first_not_of (' ');
308 if ((pos != std::string::npos) && (pos > 0))
309 raw_command_string = raw_command_string.substr (pos);
310 }
311 else
312 {
313 result.AppendError ("Error parsing command string. No alias created.");
314 result.SetStatus (eReturnStatusFailed);
315 return false;
316 }
317
318
319 // Verify that the command is alias-able.
320 if (m_interpreter.CommandExists (alias_command.c_str()))
321 {
322 result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be redefined.\n",
323 alias_command.c_str());
324 result.SetStatus (eReturnStatusFailed);
325 return false;
326 }
327
328 // Get CommandObject that is being aliased. The command name is read from the front of raw_command_string.
329 // raw_command_string is returned with the name of the command object stripped off the front.
330 CommandObject *cmd_obj = m_interpreter.GetCommandObjectForCommand (raw_command_string);
331
332 if (!cmd_obj)
333 {
334 result.AppendErrorWithFormat ("Invalid command given to 'alias'. '%s' does not begin with a valid command."
335 " No alias created.", raw_command_string.c_str());
336 result.SetStatus (eReturnStatusFailed);
337 return false;
338 }
339 else if (!cmd_obj->WantsRawCommandString ())
340 {
341 // Note that args was initialized with the original command, and has not been updated to this point.
342 // Therefore can we pass it to the version of Execute that does not need/expect raw input in the alias.
343 return Execute (args, result);
344 }
345 else
346 {
347 // Verify & handle any options/arguments passed to the alias command
348
349 OptionArgVectorSP option_arg_vector_sp = OptionArgVectorSP (new OptionArgVector);
350 OptionArgVector *option_arg_vector = option_arg_vector_sp.get();
351
352 // Check to see if there's anything left in the input command string.
353 if (raw_command_string.size() > 0)
354 {
355
356 // Check to see if the command being aliased can take any command options.
357 Options *options = cmd_obj->GetOptions();
358 if (options)
359 {
360 // See if any options were specified as part of the alias; if so, handle them appropriately
361 options->ResetOptionValues ();
362 Args tmp_args (raw_command_string.c_str());
363 args.Unshift ("dummy_arg");
364 args.ParseAliasOptions (*options, result, option_arg_vector, raw_command_string);
365 args.Shift ();
366 if (result.Succeeded())
367 options->VerifyPartialOptions (result);
368 if (!result.Succeeded() && result.GetStatus() != lldb::eReturnStatusStarted)
369 {
370 result.AppendError ("Unable to create requested alias.\n");
371 return false;
372 }
373 }
374 // Anything remaining must be plain raw input. Push it in as a single raw input argument.
375 if (raw_command_string.size() > 0)
376 option_arg_vector->push_back (OptionArgPair ("<argument>",
377 OptionArgValue (-1,
378 raw_command_string)));
379 }
380
381 // Create the alias
382 if (m_interpreter.AliasExists (alias_command.c_str())
383 || m_interpreter.UserCommandExists (alias_command.c_str()))
384 {
385 OptionArgVectorSP temp_option_arg_sp (m_interpreter.GetAliasOptions (alias_command.c_str()));
386 if (temp_option_arg_sp.get())
387 {
388 if (option_arg_vector->size() == 0)
389 m_interpreter.RemoveAliasOptions (alias_command.c_str());
390 }
391 result.AppendWarningWithFormat ("Overwriting existing definition for '%s'.\n",
392 alias_command.c_str());
393 }
394
395 CommandObjectSP cmd_obj_sp = m_interpreter.GetCommandSPExact (cmd_obj->GetCommandName(), false);
Caroline Tice56d2fc42010-12-14 18:51:39 +0000396 if (cmd_obj_sp)
397 {
398 m_interpreter.AddAlias (alias_command.c_str(), cmd_obj_sp);
399 if (option_arg_vector->size() > 0)
400 m_interpreter.AddOrReplaceAliasOptions (alias_command.c_str(), option_arg_vector_sp);
401 result.SetStatus (eReturnStatusSuccessFinishNoResult);
402 }
403 else
404 {
405 result.AppendError ("Unable to create requested alias.\n");
406 result.SetStatus (eReturnStatusFailed);
407 }
Caroline Ticee0da7a52010-12-09 22:52:49 +0000408 }
409 return result.Succeeded();
410 }
Jim Ingham767af882010-07-07 03:36:20 +0000411
412 bool
413 Execute
414 (
Jim Ingham767af882010-07-07 03:36:20 +0000415 Args& args,
416 CommandReturnObject &result
417 )
418 {
Caroline Tice8bb61f02010-09-21 23:25:40 +0000419 size_t argc = args.GetArgumentCount();
Jim Ingham767af882010-07-07 03:36:20 +0000420
421 if (argc < 2)
Greg Clayton54e7afa2010-07-09 20:39:50 +0000422 {
Jim Ingham767af882010-07-07 03:36:20 +0000423 result.AppendError ("'alias' requires at least two arguments");
424 result.SetStatus (eReturnStatusFailed);
425 return false;
Greg Clayton54e7afa2010-07-09 20:39:50 +0000426 }
Jim Ingham767af882010-07-07 03:36:20 +0000427
428 const std::string alias_command = args.GetArgumentAtIndex(0);
429 const std::string actual_command = args.GetArgumentAtIndex(1);
430
431 args.Shift(); // Shift the alias command word off the argument vector.
432 args.Shift(); // Shift the old command word off the argument vector.
433
434 // Verify that the command is alias'able, and get the appropriate command object.
435
Greg Clayton238c0a12010-09-18 01:14:36 +0000436 if (m_interpreter.CommandExists (alias_command.c_str()))
Jim Ingham767af882010-07-07 03:36:20 +0000437 {
438 result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be redefined.\n",
439 alias_command.c_str());
440 result.SetStatus (eReturnStatusFailed);
441 }
442 else
443 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000444 CommandObjectSP command_obj_sp(m_interpreter.GetCommandSPExact (actual_command.c_str(), true));
Jim Ingham767af882010-07-07 03:36:20 +0000445 CommandObjectSP subcommand_obj_sp;
446 bool use_subcommand = false;
447 if (command_obj_sp.get())
448 {
449 CommandObject *cmd_obj = command_obj_sp.get();
Greg Clayton54e7afa2010-07-09 20:39:50 +0000450 CommandObject *sub_cmd_obj = NULL;
Jim Ingham767af882010-07-07 03:36:20 +0000451 OptionArgVectorSP option_arg_vector_sp = OptionArgVectorSP (new OptionArgVector);
452 OptionArgVector *option_arg_vector = option_arg_vector_sp.get();
453
Caroline Ticee0da7a52010-12-09 22:52:49 +0000454 while (cmd_obj->IsMultiwordObject() && args.GetArgumentCount() > 0)
Jim Ingham767af882010-07-07 03:36:20 +0000455 {
456 if (argc >= 3)
457 {
458 const std::string sub_command = args.GetArgumentAtIndex(0);
459 assert (sub_command.length() != 0);
460 subcommand_obj_sp =
461 (((CommandObjectMultiword *) cmd_obj)->GetSubcommandSP (sub_command.c_str()));
462 if (subcommand_obj_sp.get())
463 {
464 sub_cmd_obj = subcommand_obj_sp.get();
465 use_subcommand = true;
466 args.Shift(); // Shift the sub_command word off the argument vector.
Caroline Ticee0da7a52010-12-09 22:52:49 +0000467 cmd_obj = sub_cmd_obj;
Jim Ingham767af882010-07-07 03:36:20 +0000468 }
469 else
470 {
Caroline Tice5d53b622010-11-02 19:00:04 +0000471 result.AppendErrorWithFormat("'%s' is not a valid sub-command of '%s'. "
472 "Unable to create alias.\n",
473 sub_command.c_str(), actual_command.c_str());
Jim Ingham767af882010-07-07 03:36:20 +0000474 result.SetStatus (eReturnStatusFailed);
475 return false;
476 }
477 }
478 }
479
480 // Verify & handle any options/arguments passed to the alias command
481
482 if (args.GetArgumentCount () > 0)
483 {
Jim Ingham767af882010-07-07 03:36:20 +0000484 if ((!use_subcommand && (cmd_obj->GetOptions() != NULL))
485 || (use_subcommand && (sub_cmd_obj->GetOptions() != NULL)))
486 {
487 Options *options;
488 if (use_subcommand)
489 options = sub_cmd_obj->GetOptions();
490 else
491 options = cmd_obj->GetOptions();
492 options->ResetOptionValues ();
Caroline Ticee0da7a52010-12-09 22:52:49 +0000493 std::string empty_string;
Jim Ingham767af882010-07-07 03:36:20 +0000494 args.Unshift ("dummy_arg");
Caroline Ticee0da7a52010-12-09 22:52:49 +0000495 args.ParseAliasOptions (*options, result, option_arg_vector, empty_string);
Jim Ingham767af882010-07-07 03:36:20 +0000496 args.Shift ();
497 if (result.Succeeded())
498 options->VerifyPartialOptions (result);
Caroline Tice8bb61f02010-09-21 23:25:40 +0000499 if (!result.Succeeded() && result.GetStatus() != lldb::eReturnStatusStarted)
500 {
501 result.AppendError ("Unable to create requested command alias.\n");
Caroline Ticee6866a32010-10-28 23:17:48 +0000502 return false;
Caroline Tice8bb61f02010-09-21 23:25:40 +0000503 }
Jim Ingham767af882010-07-07 03:36:20 +0000504 }
Caroline Tice8bb61f02010-09-21 23:25:40 +0000505
506 // Anything remaining in args must be a plain argument.
507
508 argc = args.GetArgumentCount();
509 for (size_t i = 0; i < argc; ++i)
Caroline Tice44c841d2010-12-07 19:58:26 +0000510 if (strcmp (args.GetArgumentAtIndex (i), "") != 0)
511 option_arg_vector->push_back
512 (OptionArgPair ("<argument>",
513 OptionArgValue (-1,
514 std::string (args.GetArgumentAtIndex (i)))));
Jim Ingham767af882010-07-07 03:36:20 +0000515 }
516
517 // Create the alias.
518
Greg Clayton238c0a12010-09-18 01:14:36 +0000519 if (m_interpreter.AliasExists (alias_command.c_str())
520 || m_interpreter.UserCommandExists (alias_command.c_str()))
Jim Ingham767af882010-07-07 03:36:20 +0000521 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000522 OptionArgVectorSP tmp_option_arg_sp (m_interpreter.GetAliasOptions (alias_command.c_str()));
Jim Ingham767af882010-07-07 03:36:20 +0000523 if (tmp_option_arg_sp.get())
524 {
525 if (option_arg_vector->size() == 0)
Greg Clayton238c0a12010-09-18 01:14:36 +0000526 m_interpreter.RemoveAliasOptions (alias_command.c_str());
Jim Ingham767af882010-07-07 03:36:20 +0000527 }
528 result.AppendWarningWithFormat ("Overwriting existing definition for '%s'.\n",
529 alias_command.c_str());
530 }
531
532 if (use_subcommand)
Greg Clayton238c0a12010-09-18 01:14:36 +0000533 m_interpreter.AddAlias (alias_command.c_str(), subcommand_obj_sp);
Jim Ingham767af882010-07-07 03:36:20 +0000534 else
Greg Clayton238c0a12010-09-18 01:14:36 +0000535 m_interpreter.AddAlias (alias_command.c_str(), command_obj_sp);
Jim Ingham767af882010-07-07 03:36:20 +0000536 if (option_arg_vector->size() > 0)
Greg Clayton238c0a12010-09-18 01:14:36 +0000537 m_interpreter.AddOrReplaceAliasOptions (alias_command.c_str(), option_arg_vector_sp);
Jim Ingham767af882010-07-07 03:36:20 +0000538 result.SetStatus (eReturnStatusSuccessFinishNoResult);
539 }
540 else
541 {
542 result.AppendErrorWithFormat ("'%s' is not an existing command.\n", actual_command.c_str());
543 result.SetStatus (eReturnStatusFailed);
Caroline Ticee6866a32010-10-28 23:17:48 +0000544 return false;
Jim Ingham767af882010-07-07 03:36:20 +0000545 }
546 }
547
548 return result.Succeeded();
549 }
550};
551
552#pragma mark CommandObjectCommandsUnalias
553//-------------------------------------------------------------------------
554// CommandObjectCommandsUnalias
555//-------------------------------------------------------------------------
556
557class CommandObjectCommandsUnalias : public CommandObject
558{
559public:
Greg Clayton238c0a12010-09-18 01:14:36 +0000560 CommandObjectCommandsUnalias (CommandInterpreter &interpreter) :
561 CommandObject (interpreter,
562 "commands unalias",
Caroline Tice146292c2010-09-12 04:56:10 +0000563 "Allow the user to remove/delete a user-defined command abbreviation.",
Caroline Tice43b014a2010-10-04 22:28:36 +0000564 NULL)
Jim Ingham767af882010-07-07 03:36:20 +0000565 {
Caroline Tice43b014a2010-10-04 22:28:36 +0000566 CommandArgumentEntry arg;
567 CommandArgumentData alias_arg;
568
569 // Define the first (and only) variant of this arg.
570 alias_arg.arg_type = eArgTypeAliasName;
571 alias_arg.arg_repetition = eArgRepeatPlain;
572
573 // There is only one variant this argument could be; put it into the argument entry.
574 arg.push_back (alias_arg);
575
576 // Push the data for the first argument into the m_arguments vector.
577 m_arguments.push_back (arg);
Jim Ingham767af882010-07-07 03:36:20 +0000578 }
579
580 ~CommandObjectCommandsUnalias()
581 {
582 }
583
584
585 bool
586 Execute
587 (
Jim Ingham767af882010-07-07 03:36:20 +0000588 Args& args,
589 CommandReturnObject &result
590 )
591 {
592 CommandObject::CommandMap::iterator pos;
593 CommandObject *cmd_obj;
594
595 if (args.GetArgumentCount() != 0)
596 {
597 const char *command_name = args.GetArgumentAtIndex(0);
Greg Clayton238c0a12010-09-18 01:14:36 +0000598 cmd_obj = m_interpreter.GetCommandObject(command_name);
Jim Ingham767af882010-07-07 03:36:20 +0000599 if (cmd_obj)
600 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000601 if (m_interpreter.CommandExists (command_name))
Jim Ingham767af882010-07-07 03:36:20 +0000602 {
603 result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be removed.\n",
604 command_name);
605 result.SetStatus (eReturnStatusFailed);
606 }
607 else
608 {
609
Greg Clayton238c0a12010-09-18 01:14:36 +0000610 if (m_interpreter.RemoveAlias (command_name) == false)
Jim Ingham767af882010-07-07 03:36:20 +0000611 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000612 if (m_interpreter.AliasExists (command_name))
Jim Ingham767af882010-07-07 03:36:20 +0000613 result.AppendErrorWithFormat ("Error occurred while attempting to unalias '%s'.\n",
614 command_name);
615 else
616 result.AppendErrorWithFormat ("'%s' is not an existing alias.\n", command_name);
617 result.SetStatus (eReturnStatusFailed);
618 }
619 else
620 result.SetStatus (eReturnStatusSuccessFinishNoResult);
621 }
622 }
623 else
624 {
625 result.AppendErrorWithFormat ("'%s' is not a known command.\nTry 'help' to see a "
626 "current list of commands.\n",
627 command_name);
628 result.SetStatus (eReturnStatusFailed);
629 }
630 }
631 else
632 {
633 result.AppendError ("must call 'unalias' with a valid alias");
634 result.SetStatus (eReturnStatusFailed);
635 }
636
637 return result.Succeeded();
638 }
639};
640
641#pragma mark CommandObjectMultiwordCommands
642
643//-------------------------------------------------------------------------
644// CommandObjectMultiwordCommands
645//-------------------------------------------------------------------------
646
647CommandObjectMultiwordCommands::CommandObjectMultiwordCommands (CommandInterpreter &interpreter) :
Greg Clayton238c0a12010-09-18 01:14:36 +0000648 CommandObjectMultiword (interpreter,
649 "commands",
Caroline Ticec1ad82e2010-09-07 22:38:08 +0000650 "A set of commands for managing or customizing the debugger commands.",
Jim Ingham767af882010-07-07 03:36:20 +0000651 "commands <subcommand> [<subcommand-options>]")
652{
Greg Clayton238c0a12010-09-18 01:14:36 +0000653 LoadSubCommand ("source", CommandObjectSP (new CommandObjectCommandsSource (interpreter)));
654 LoadSubCommand ("alias", CommandObjectSP (new CommandObjectCommandsAlias (interpreter)));
655 LoadSubCommand ("unalias", CommandObjectSP (new CommandObjectCommandsUnalias (interpreter)));
Jim Ingham767af882010-07-07 03:36:20 +0000656}
657
658CommandObjectMultiwordCommands::~CommandObjectMultiwordCommands ()
659{
660}
661