1ebc09c36SJim Ingham //===-- CommandObjectSource.cpp ---------------------------------*- C++ -*-===//
2ebc09c36SJim Ingham //
3ebc09c36SJim Ingham //                     The LLVM Compiler Infrastructure
4ebc09c36SJim Ingham //
5ebc09c36SJim Ingham // This file is distributed under the University of Illinois Open Source
6ebc09c36SJim Ingham // License. See LICENSE.TXT for details.
7ebc09c36SJim Ingham //
8ebc09c36SJim Ingham //===----------------------------------------------------------------------===//
9ebc09c36SJim Ingham 
10ebc09c36SJim Ingham #include "CommandObjectCommands.h"
11ebc09c36SJim Ingham 
12ebc09c36SJim Ingham // C Includes
13ebc09c36SJim Ingham // C++ Includes
14ebc09c36SJim Ingham // Other libraries and framework includes
15ebc09c36SJim Ingham // Project includes
16ebc09c36SJim Ingham #include "lldb/Interpreter/Args.h"
17ebc09c36SJim Ingham #include "lldb/Core/Debugger.h"
18ebc09c36SJim Ingham #include "lldb/Interpreter/CommandInterpreter.h"
19ebc09c36SJim Ingham #include "lldb/Interpreter/CommandReturnObject.h"
20ebc09c36SJim Ingham #include "lldb/Interpreter/Options.h"
21ebc09c36SJim Ingham 
22ebc09c36SJim Ingham using namespace lldb;
23ebc09c36SJim Ingham using namespace lldb_private;
24ebc09c36SJim Ingham 
25ebc09c36SJim Ingham const char *k_space_characters = "\t\n\v\f\r ";
26ebc09c36SJim Ingham 
27ebc09c36SJim Ingham //-------------------------------------------------------------------------
28ebc09c36SJim Ingham // CommandObjectCommandsSource
29ebc09c36SJim Ingham //-------------------------------------------------------------------------
30ebc09c36SJim Ingham 
31ebc09c36SJim Ingham class CommandObjectCommandsSource : public CommandObject
32ebc09c36SJim Ingham {
33ebc09c36SJim Ingham public:
34ebc09c36SJim Ingham     CommandObjectCommandsSource() :
35ebc09c36SJim Ingham         CommandObject ("commands source",
36ebc09c36SJim Ingham                    "Reads in debugger commands from the file <filename> and executes them.",
37ebc09c36SJim Ingham                    "command source <filename>")
38ebc09c36SJim Ingham     {
39ebc09c36SJim Ingham     }
40ebc09c36SJim Ingham 
41ebc09c36SJim Ingham     ~CommandObjectCommandsSource ()
42ebc09c36SJim Ingham     {
43ebc09c36SJim Ingham     }
44ebc09c36SJim Ingham 
45ebc09c36SJim Ingham     bool
46ebc09c36SJim Ingham     Execute
47ebc09c36SJim Ingham     (
48ebc09c36SJim Ingham         CommandInterpreter &interpreter,
49ebc09c36SJim Ingham         Args& args,
50ebc09c36SJim Ingham         CommandReturnObject &result
51ebc09c36SJim Ingham     )
52ebc09c36SJim Ingham     {
53ebc09c36SJim Ingham         const int argc = args.GetArgumentCount();
54ebc09c36SJim Ingham         if (argc == 1)
55ebc09c36SJim Ingham         {
56ebc09c36SJim Ingham             const char *filename = args.GetArgumentAtIndex(0);
57ebc09c36SJim Ingham             bool success = true;
58ebc09c36SJim Ingham 
59ebc09c36SJim Ingham             result.AppendMessageWithFormat ("Executing commands in '%s'.\n", filename);
60ebc09c36SJim Ingham 
61ebc09c36SJim Ingham             FileSpec cmd_file (filename);
62ebc09c36SJim Ingham             if (cmd_file.Exists())
63ebc09c36SJim Ingham             {
64ebc09c36SJim Ingham                 STLStringArray commands;
65ebc09c36SJim Ingham                 success = cmd_file.ReadFileLines (commands);
66ebc09c36SJim Ingham 
67ebc09c36SJim Ingham                 STLStringArray::iterator pos = commands.begin();
68ebc09c36SJim Ingham 
69ebc09c36SJim Ingham                 // Trim out any empty lines or lines that start with the comment
70ebc09c36SJim Ingham                 // char '#'
71ebc09c36SJim Ingham                 while (pos != commands.end())
72ebc09c36SJim Ingham                 {
73ebc09c36SJim Ingham                     bool remove_string = false;
74ebc09c36SJim Ingham                     size_t non_space = pos->find_first_not_of (k_space_characters);
75ebc09c36SJim Ingham                     if (non_space == std::string::npos)
76ebc09c36SJim Ingham                         remove_string = true; // Empty line
77ebc09c36SJim Ingham                     else if ((*pos)[non_space] == '#')
78ebc09c36SJim Ingham                         remove_string = true; // Comment line that starts with '#'
79ebc09c36SJim Ingham 
80ebc09c36SJim Ingham                     if (remove_string)
81ebc09c36SJim Ingham                         pos = commands.erase(pos);
82ebc09c36SJim Ingham                     else
83ebc09c36SJim Ingham                         ++pos;
84ebc09c36SJim Ingham                 }
85ebc09c36SJim Ingham 
86ebc09c36SJim Ingham                 if (commands.size() > 0)
87ebc09c36SJim Ingham                 {
88ebc09c36SJim Ingham                     const size_t num_commands = commands.size();
89ebc09c36SJim Ingham                     size_t i;
90ebc09c36SJim Ingham                     for (i = 0; i<num_commands; ++i)
91ebc09c36SJim Ingham                     {
92ebc09c36SJim Ingham                         result.GetOutputStream().Printf("%s %s\n", interpreter.GetPrompt(), commands[i].c_str());
93ebc09c36SJim Ingham                         if (!interpreter.HandleCommand(commands[i].c_str(), false, result))
94ebc09c36SJim Ingham                             break;
95ebc09c36SJim Ingham                     }
96ebc09c36SJim Ingham 
97ebc09c36SJim Ingham                     if (i < num_commands)
98ebc09c36SJim Ingham                     {
99ebc09c36SJim Ingham                         result.AppendErrorWithFormat("Aborting source of '%s' after command '%s' failed.\n",
100ebc09c36SJim Ingham                                                      filename, commands[i].c_str());
101ebc09c36SJim Ingham                         result.SetStatus (eReturnStatusSuccessFinishResult);
102ebc09c36SJim Ingham                     }
103ebc09c36SJim Ingham                     else
104ebc09c36SJim Ingham                     {
105ebc09c36SJim Ingham                         success = true;
106ebc09c36SJim Ingham                         result.SetStatus (eReturnStatusFailed);
107ebc09c36SJim Ingham                     }
108ebc09c36SJim Ingham                 }
109ebc09c36SJim Ingham             }
110ebc09c36SJim Ingham             else
111ebc09c36SJim Ingham             {
112ebc09c36SJim Ingham                 result.AppendErrorWithFormat ("File '%s' does not exist.\n", filename);
113ebc09c36SJim Ingham                 result.SetStatus (eReturnStatusFailed);
114ebc09c36SJim Ingham                 success = false;
115ebc09c36SJim Ingham             }
116ebc09c36SJim Ingham 
117ebc09c36SJim Ingham             if (success)
118ebc09c36SJim Ingham             {
119ebc09c36SJim Ingham                 result.SetStatus (eReturnStatusSuccessFinishNoResult);
120ebc09c36SJim Ingham             }
121ebc09c36SJim Ingham         }
122ebc09c36SJim Ingham         else
123ebc09c36SJim Ingham         {
124ebc09c36SJim Ingham             result.AppendErrorWithFormat("'%s' takes exactly one executable filename argument.\n", GetCommandName());
125ebc09c36SJim Ingham             result.SetStatus (eReturnStatusFailed);
126ebc09c36SJim Ingham         }
127ebc09c36SJim Ingham         return result.Succeeded();
128ebc09c36SJim Ingham 
129ebc09c36SJim Ingham     }
130ebc09c36SJim Ingham };
131ebc09c36SJim Ingham 
132ebc09c36SJim Ingham #pragma mark CommandObjectCommandsAlias
133ebc09c36SJim Ingham //-------------------------------------------------------------------------
134ebc09c36SJim Ingham // CommandObjectCommandsAlias
135ebc09c36SJim Ingham //-------------------------------------------------------------------------
136ebc09c36SJim Ingham 
137ebc09c36SJim Ingham class CommandObjectCommandsAlias : public CommandObject
138ebc09c36SJim Ingham {
139ebc09c36SJim Ingham public:
140ebc09c36SJim Ingham     CommandObjectCommandsAlias () :
141ebc09c36SJim Ingham         CommandObject ("commands alias",
142ebc09c36SJim Ingham                          "Allows users to define their own debugger command abbreviations.",
143*0708e2c2SSean Callanan                          "commands alias <new_command> <old_command> [<options-for-aliased-command>]")
144ebc09c36SJim Ingham     {
145ebc09c36SJim Ingham         SetHelpLong(
146ebc09c36SJim Ingham     "'alias' allows the user to create a short-cut or abbreviation for long \n\
147ebc09c36SJim Ingham     commands, multi-word commands, and commands that take particular options. \n\
148ebc09c36SJim Ingham     Below are some simple examples of how one might use the 'alias' command: \n\
1499e40956aSGreg Clayton     \n    'command alias sc script'           // Creates the abbreviation 'sc' for the 'script' \n\
150ebc09c36SJim Ingham                                         // command. \n\
1519e40956aSGreg Clayton     'command alias bp breakpoint'       // Creates the abbreviation 'bp' for the 'breakpoint' \n\
152ebc09c36SJim Ingham                                         // command.  Since breakpoint commands are two-word \n\
153ebc09c36SJim Ingham                                         // commands, the user will still need to enter the \n\
154ebc09c36SJim Ingham                                         // second word after 'bp', e.g. 'bp enable' or \n\
155ebc09c36SJim Ingham                                         // 'bp delete'. \n\
1569e40956aSGreg Clayton     'command alias bpi breakpoint list' // Creates the abbreviation 'bpi' for the \n\
157ebc09c36SJim Ingham                                         // two-word command 'breakpoint list'. \n\
158ebc09c36SJim Ingham     \nAn alias can include some options for the command, with the values either \n\
159ebc09c36SJim Ingham     filled in at the time the alias is created, or specified as positional \n\
160ebc09c36SJim Ingham     arguments, to be filled in when the alias is invoked.  The following example \n\
161ebc09c36SJim Ingham     shows how to create aliases with options: \n\
162ebc09c36SJim Ingham     \n\
1639e40956aSGreg Clayton     'command alias bfl breakpoint set -f %1 -l %2' \n\
164ebc09c36SJim Ingham     \nThis creates the abbreviation 'bfl' (for break-file-line), with the -f and -l \n\
165ebc09c36SJim Ingham     options already part of the alias.  So if the user wants to set a breakpoint \n\
166ebc09c36SJim Ingham     by file and line without explicitly having to use the -f and -l options, the \n\
167ebc09c36SJim Ingham     user can now use 'bfl' instead.  The '%1' and '%2' are positional placeholders \n\
168ebc09c36SJim Ingham     for the actual arguments that will be passed when the alias command is used. \n\
169ebc09c36SJim Ingham     The number in the placeholder refers to the position/order the actual value \n\
170ebc09c36SJim Ingham     occupies when the alias is used.  So all the occurrences of '%1' in the alias \n\
171ebc09c36SJim Ingham     will be replaced with the first argument, all the occurrences of '%2' in the \n\
172ebc09c36SJim Ingham     alias will be replaced with the second argument, and so on.  This also allows \n\
173ebc09c36SJim Ingham     actual arguments to be used multiple times within an alias (see 'process \n\
174ebc09c36SJim Ingham     launch' example below).  So in the 'bfl' case, the actual file value will be \n\
175ebc09c36SJim Ingham     filled in with the first argument following 'bfl' and the actual line number \n\
176ebc09c36SJim Ingham     value will be filled in with the second argument.  The user would use this \n\
177ebc09c36SJim Ingham     alias as follows: \n\
178*0708e2c2SSean Callanan     \n    (dbg)  commands alias bfl breakpoint set -f %1 -l %2 \n\
179ebc09c36SJim Ingham     <... some time later ...> \n\
180ebc09c36SJim Ingham     (dbg)  bfl my-file.c 137 \n\
181ebc09c36SJim Ingham     \nThis would be the same as if the user had entered \n\
182ebc09c36SJim Ingham     'breakpoint set -f my-file.c -l 137'. \n\
183ebc09c36SJim Ingham     \nAnother example: \n\
184*0708e2c2SSean Callanan     \n    (dbg)  commands alias pltty  process launch -s -o %1 -e %1 \n\
185ebc09c36SJim Ingham     (dbg)  pltty /dev/tty0 \n\
186ebc09c36SJim Ingham            // becomes 'process launch -s -o /dev/tty0 -e /dev/tty0' \n\
187ebc09c36SJim Ingham     \nIf the user always wanted to pass the same value to a particular option, the \n\
188ebc09c36SJim Ingham     alias could be defined with that value directly in the alias as a constant, \n\
189ebc09c36SJim Ingham     rather than using a positional placeholder: \n\
190*0708e2c2SSean Callanan     \n    commands alias bl3  breakpoint set -f %1 -l 3  // Always sets a breakpoint on line \n\
191ebc09c36SJim Ingham                                                    // 3 of whatever file is indicated. \n");
192ebc09c36SJim Ingham 
193ebc09c36SJim Ingham     }
194ebc09c36SJim Ingham 
195ebc09c36SJim Ingham     ~CommandObjectCommandsAlias ()
196ebc09c36SJim Ingham     {
197ebc09c36SJim Ingham     }
198ebc09c36SJim Ingham 
199ebc09c36SJim Ingham 
200ebc09c36SJim Ingham     bool
201ebc09c36SJim Ingham     Execute
202ebc09c36SJim Ingham     (
203ebc09c36SJim Ingham         CommandInterpreter &interpreter,
204ebc09c36SJim Ingham         Args& args,
205ebc09c36SJim Ingham         CommandReturnObject &result
206ebc09c36SJim Ingham     )
207ebc09c36SJim Ingham     {
208c982c768SGreg Clayton         const size_t argc = args.GetArgumentCount();
209ebc09c36SJim Ingham 
210ebc09c36SJim Ingham         if (argc < 2)
211ebc09c36SJim Ingham         {
212ebc09c36SJim Ingham             result.AppendError ("'alias' requires at least two arguments");
213ebc09c36SJim Ingham             result.SetStatus (eReturnStatusFailed);
214ebc09c36SJim Ingham             return false;
215ebc09c36SJim Ingham         }
216ebc09c36SJim Ingham 
217ebc09c36SJim Ingham         const std::string alias_command = args.GetArgumentAtIndex(0);
218ebc09c36SJim Ingham         const std::string actual_command = args.GetArgumentAtIndex(1);
219ebc09c36SJim Ingham 
220ebc09c36SJim Ingham         args.Shift();  // Shift the alias command word off the argument vector.
221ebc09c36SJim Ingham         args.Shift();  // Shift the old command word off the argument vector.
222ebc09c36SJim Ingham 
223ebc09c36SJim Ingham         // Verify that the command is alias'able, and get the appropriate command object.
224ebc09c36SJim Ingham 
225ebc09c36SJim Ingham         if (interpreter.CommandExists (alias_command.c_str()))
226ebc09c36SJim Ingham         {
227ebc09c36SJim Ingham             result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be redefined.\n",
228ebc09c36SJim Ingham                                          alias_command.c_str());
229ebc09c36SJim Ingham             result.SetStatus (eReturnStatusFailed);
230ebc09c36SJim Ingham         }
231ebc09c36SJim Ingham         else
232ebc09c36SJim Ingham         {
233ebc09c36SJim Ingham              CommandObjectSP command_obj_sp(interpreter.GetCommandSPExact (actual_command.c_str(), true));
234ebc09c36SJim Ingham              CommandObjectSP subcommand_obj_sp;
235ebc09c36SJim Ingham              bool use_subcommand = false;
236ebc09c36SJim Ingham              if (command_obj_sp.get())
237ebc09c36SJim Ingham              {
238ebc09c36SJim Ingham                  CommandObject *cmd_obj = command_obj_sp.get();
239c982c768SGreg Clayton                  CommandObject *sub_cmd_obj = NULL;
240ebc09c36SJim Ingham                  OptionArgVectorSP option_arg_vector_sp = OptionArgVectorSP (new OptionArgVector);
241ebc09c36SJim Ingham                  OptionArgVector *option_arg_vector = option_arg_vector_sp.get();
242ebc09c36SJim Ingham 
243ebc09c36SJim Ingham                  if (cmd_obj->IsMultiwordObject())
244ebc09c36SJim Ingham                  {
245ebc09c36SJim Ingham                      if (argc >= 3)
246ebc09c36SJim Ingham                      {
247ebc09c36SJim Ingham                          const std::string sub_command = args.GetArgumentAtIndex(0);
248ebc09c36SJim Ingham                          assert (sub_command.length() != 0);
249ebc09c36SJim Ingham                          subcommand_obj_sp =
250ebc09c36SJim Ingham                                            (((CommandObjectMultiword *) cmd_obj)->GetSubcommandSP (sub_command.c_str()));
251ebc09c36SJim Ingham                          if (subcommand_obj_sp.get())
252ebc09c36SJim Ingham                          {
253ebc09c36SJim Ingham                              sub_cmd_obj = subcommand_obj_sp.get();
254ebc09c36SJim Ingham                              use_subcommand = true;
255ebc09c36SJim Ingham                              args.Shift();  // Shift the sub_command word off the argument vector.
256ebc09c36SJim Ingham                          }
257ebc09c36SJim Ingham                          else
258ebc09c36SJim Ingham                          {
259ebc09c36SJim Ingham                              result.AppendErrorWithFormat ("Error occurred while attempting to look up command '%s %s'.\n",
260ebc09c36SJim Ingham                                                           alias_command.c_str(), sub_command.c_str());
261ebc09c36SJim Ingham                              result.SetStatus (eReturnStatusFailed);
262ebc09c36SJim Ingham                              return false;
263ebc09c36SJim Ingham                          }
264ebc09c36SJim Ingham                      }
265ebc09c36SJim Ingham                  }
266ebc09c36SJim Ingham 
267ebc09c36SJim Ingham                  // Verify & handle any options/arguments passed to the alias command
268ebc09c36SJim Ingham 
269ebc09c36SJim Ingham                  if (args.GetArgumentCount () > 0)
270ebc09c36SJim Ingham                  {
271ebc09c36SJim Ingham                      if ((!use_subcommand && (cmd_obj->WantsRawCommandString()))
272ebc09c36SJim Ingham                          || (use_subcommand && (sub_cmd_obj->WantsRawCommandString())))
273ebc09c36SJim Ingham                      {
274ebc09c36SJim Ingham                          result.AppendErrorWithFormat ("'%s' cannot be aliased with any options or arguments.\n",
275ebc09c36SJim Ingham                                                       (use_subcommand ? sub_cmd_obj->GetCommandName()
276ebc09c36SJim Ingham                                                                       : cmd_obj->GetCommandName()));
277ebc09c36SJim Ingham                          result.SetStatus (eReturnStatusFailed);
278ebc09c36SJim Ingham                          return false;
279ebc09c36SJim Ingham                      }
280ebc09c36SJim Ingham 
281ebc09c36SJim Ingham                      // options or arguments have been passed to the alias command, and must be
282ebc09c36SJim Ingham                      // verified & processed here.
283ebc09c36SJim Ingham                      if ((!use_subcommand && (cmd_obj->GetOptions() != NULL))
284ebc09c36SJim Ingham                          || (use_subcommand && (sub_cmd_obj->GetOptions() != NULL)))
285ebc09c36SJim Ingham                      {
286ebc09c36SJim Ingham                          Options *options;
287ebc09c36SJim Ingham                          if (use_subcommand)
288ebc09c36SJim Ingham                              options = sub_cmd_obj->GetOptions();
289ebc09c36SJim Ingham                          else
290ebc09c36SJim Ingham                              options = cmd_obj->GetOptions();
291ebc09c36SJim Ingham                          options->ResetOptionValues ();
292ebc09c36SJim Ingham                          args.Unshift ("dummy_arg");
293ebc09c36SJim Ingham                          args.ParseAliasOptions (*options, result, option_arg_vector);
294ebc09c36SJim Ingham                          args.Shift ();
295ebc09c36SJim Ingham                          if (result.Succeeded())
296ebc09c36SJim Ingham                              options->VerifyPartialOptions (result);
297ebc09c36SJim Ingham                          if (!result.Succeeded())
298ebc09c36SJim Ingham                              return false;
299ebc09c36SJim Ingham                      }
300ebc09c36SJim Ingham                      else
301ebc09c36SJim Ingham                      {
302c982c768SGreg Clayton                          for (size_t i = 0; i < argc; ++i)
303ebc09c36SJim Ingham                              option_arg_vector->push_back (OptionArgPair ("<argument>",
304ebc09c36SJim Ingham                                                                           std::string (args.GetArgumentAtIndex (i))));
305ebc09c36SJim Ingham                      }
306ebc09c36SJim Ingham                  }
307ebc09c36SJim Ingham 
308ebc09c36SJim Ingham                  // Create the alias.
309ebc09c36SJim Ingham 
310ebc09c36SJim Ingham                  if (interpreter.AliasExists (alias_command.c_str())
311ebc09c36SJim Ingham                      || interpreter.UserCommandExists (alias_command.c_str()))
312ebc09c36SJim Ingham                  {
313ebc09c36SJim Ingham                      OptionArgVectorSP tmp_option_arg_sp (interpreter.GetAliasOptions (alias_command.c_str()));
314ebc09c36SJim Ingham                      if (tmp_option_arg_sp.get())
315ebc09c36SJim Ingham                      {
316ebc09c36SJim Ingham                          if (option_arg_vector->size() == 0)
317ebc09c36SJim Ingham                              interpreter.RemoveAliasOptions (alias_command.c_str());
318ebc09c36SJim Ingham                      }
319ebc09c36SJim Ingham                      result.AppendWarningWithFormat ("Overwriting existing definition for '%s'.\n",
320ebc09c36SJim Ingham                                                      alias_command.c_str());
321ebc09c36SJim Ingham                  }
322ebc09c36SJim Ingham 
323ebc09c36SJim Ingham                  if (use_subcommand)
324ebc09c36SJim Ingham                      interpreter.AddAlias (alias_command.c_str(), subcommand_obj_sp);
325ebc09c36SJim Ingham                  else
326ebc09c36SJim Ingham                      interpreter.AddAlias (alias_command.c_str(), command_obj_sp);
327ebc09c36SJim Ingham                  if (option_arg_vector->size() > 0)
328ebc09c36SJim Ingham                      interpreter.AddOrReplaceAliasOptions (alias_command.c_str(), option_arg_vector_sp);
329ebc09c36SJim Ingham                  result.SetStatus (eReturnStatusSuccessFinishNoResult);
330ebc09c36SJim Ingham              }
331ebc09c36SJim Ingham              else
332ebc09c36SJim Ingham              {
333ebc09c36SJim Ingham                  result.AppendErrorWithFormat ("'%s' is not an existing command.\n", actual_command.c_str());
334ebc09c36SJim Ingham                  result.SetStatus (eReturnStatusFailed);
335ebc09c36SJim Ingham              }
336ebc09c36SJim Ingham         }
337ebc09c36SJim Ingham 
338ebc09c36SJim Ingham         return result.Succeeded();
339ebc09c36SJim Ingham     }
340ebc09c36SJim Ingham };
341ebc09c36SJim Ingham 
342ebc09c36SJim Ingham #pragma mark CommandObjectCommandsUnalias
343ebc09c36SJim Ingham //-------------------------------------------------------------------------
344ebc09c36SJim Ingham // CommandObjectCommandsUnalias
345ebc09c36SJim Ingham //-------------------------------------------------------------------------
346ebc09c36SJim Ingham 
347ebc09c36SJim Ingham class CommandObjectCommandsUnalias : public CommandObject
348ebc09c36SJim Ingham {
349ebc09c36SJim Ingham public:
350ebc09c36SJim Ingham     CommandObjectCommandsUnalias () :
351ebc09c36SJim Ingham         CommandObject ("commands unalias",
352ebc09c36SJim Ingham                    "Allows the user to remove/delete a user-defined command abbreviation.",
353ebc09c36SJim Ingham                    "unalias <alias-name-to-be-removed>")
354ebc09c36SJim Ingham     {
355ebc09c36SJim Ingham     }
356ebc09c36SJim Ingham 
357ebc09c36SJim Ingham     ~CommandObjectCommandsUnalias()
358ebc09c36SJim Ingham     {
359ebc09c36SJim Ingham     }
360ebc09c36SJim Ingham 
361ebc09c36SJim Ingham 
362ebc09c36SJim Ingham     bool
363ebc09c36SJim Ingham     Execute
364ebc09c36SJim Ingham     (
365ebc09c36SJim Ingham         CommandInterpreter &interpreter,
366ebc09c36SJim Ingham         Args& args,
367ebc09c36SJim Ingham         CommandReturnObject &result
368ebc09c36SJim Ingham     )
369ebc09c36SJim Ingham     {
370ebc09c36SJim Ingham         CommandObject::CommandMap::iterator pos;
371ebc09c36SJim Ingham         CommandObject *cmd_obj;
372ebc09c36SJim Ingham 
373ebc09c36SJim Ingham         if (args.GetArgumentCount() != 0)
374ebc09c36SJim Ingham         {
375ebc09c36SJim Ingham             const char *command_name = args.GetArgumentAtIndex(0);
376ebc09c36SJim Ingham             cmd_obj = interpreter.GetCommandObject(command_name);
377ebc09c36SJim Ingham             if (cmd_obj)
378ebc09c36SJim Ingham             {
379ebc09c36SJim Ingham                 if (interpreter.CommandExists (command_name))
380ebc09c36SJim Ingham                 {
381ebc09c36SJim Ingham                     result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be removed.\n",
382ebc09c36SJim Ingham                                                   command_name);
383ebc09c36SJim Ingham                     result.SetStatus (eReturnStatusFailed);
384ebc09c36SJim Ingham                 }
385ebc09c36SJim Ingham                 else
386ebc09c36SJim Ingham                 {
387ebc09c36SJim Ingham 
388ebc09c36SJim Ingham                     if (interpreter.RemoveAlias (command_name) == false)
389ebc09c36SJim Ingham                     {
390ebc09c36SJim Ingham                         if (interpreter.AliasExists (command_name))
391ebc09c36SJim Ingham                             result.AppendErrorWithFormat ("Error occurred while attempting to unalias '%s'.\n",
392ebc09c36SJim Ingham                                                           command_name);
393ebc09c36SJim Ingham                         else
394ebc09c36SJim Ingham                             result.AppendErrorWithFormat ("'%s' is not an existing alias.\n", command_name);
395ebc09c36SJim Ingham                         result.SetStatus (eReturnStatusFailed);
396ebc09c36SJim Ingham                     }
397ebc09c36SJim Ingham                     else
398ebc09c36SJim Ingham                         result.SetStatus (eReturnStatusSuccessFinishNoResult);
399ebc09c36SJim Ingham                 }
400ebc09c36SJim Ingham             }
401ebc09c36SJim Ingham             else
402ebc09c36SJim Ingham             {
403ebc09c36SJim Ingham                 result.AppendErrorWithFormat ("'%s' is not a known command.\nTry 'help' to see a "
404ebc09c36SJim Ingham                                               "current list of commands.\n",
405ebc09c36SJim Ingham                                              command_name);
406ebc09c36SJim Ingham                 result.SetStatus (eReturnStatusFailed);
407ebc09c36SJim Ingham             }
408ebc09c36SJim Ingham         }
409ebc09c36SJim Ingham         else
410ebc09c36SJim Ingham         {
411ebc09c36SJim Ingham             result.AppendError ("must call 'unalias' with a valid alias");
412ebc09c36SJim Ingham             result.SetStatus (eReturnStatusFailed);
413ebc09c36SJim Ingham         }
414ebc09c36SJim Ingham 
415ebc09c36SJim Ingham         return result.Succeeded();
416ebc09c36SJim Ingham     }
417ebc09c36SJim Ingham };
418ebc09c36SJim Ingham 
419ebc09c36SJim Ingham #pragma mark CommandObjectMultiwordCommands
420ebc09c36SJim Ingham 
421ebc09c36SJim Ingham //-------------------------------------------------------------------------
422ebc09c36SJim Ingham // CommandObjectMultiwordCommands
423ebc09c36SJim Ingham //-------------------------------------------------------------------------
424ebc09c36SJim Ingham 
425ebc09c36SJim Ingham CommandObjectMultiwordCommands::CommandObjectMultiwordCommands (CommandInterpreter &interpreter) :
426ebc09c36SJim Ingham     CommandObjectMultiword ("commands",
427ebc09c36SJim Ingham                             "Commands for managing the command interpreters commands",
428ebc09c36SJim Ingham                             "commands <subcommand> [<subcommand-options>]")
429ebc09c36SJim Ingham {
430ebc09c36SJim Ingham     LoadSubCommand (interpreter, "source",   CommandObjectSP (new CommandObjectCommandsSource ()));
431ebc09c36SJim Ingham     LoadSubCommand (interpreter, "alias",   CommandObjectSP (new CommandObjectCommandsAlias ()));
432ebc09c36SJim Ingham }
433ebc09c36SJim Ingham 
434ebc09c36SJim Ingham CommandObjectMultiwordCommands::~CommandObjectMultiwordCommands ()
435ebc09c36SJim Ingham {
436ebc09c36SJim Ingham }
437ebc09c36SJim Ingham 
438