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:
34a7015092SGreg Clayton     CommandObjectCommandsSource(CommandInterpreter &interpreter) :
35a7015092SGreg Clayton         CommandObject (interpreter,
36a7015092SGreg Clayton                        "commands source",
37e3d26315SCaroline Tice                        "Read in debugger commands from the file <filename> and execute them.",
38ebc09c36SJim Ingham                        "command source <filename>")
39ebc09c36SJim Ingham     {
40ebc09c36SJim Ingham     }
41ebc09c36SJim Ingham 
42ebc09c36SJim Ingham     ~CommandObjectCommandsSource ()
43ebc09c36SJim Ingham     {
44ebc09c36SJim Ingham     }
45ebc09c36SJim Ingham 
46ebc09c36SJim Ingham     bool
47ebc09c36SJim Ingham     Execute
48ebc09c36SJim Ingham     (
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                     size_t non_space = pos->find_first_not_of (k_space_characters);
74*0603aa9dSGreg Clayton                     // Check for empty line or comment line (lines whose first
75*0603aa9dSGreg Clayton                     // non-space character is a '#')
76*0603aa9dSGreg Clayton                     if (non_space == std::string::npos || (*pos)[non_space] == '#')
77ebc09c36SJim Ingham                         pos = commands.erase(pos);
78ebc09c36SJim Ingham                     else
79ebc09c36SJim Ingham                         ++pos;
80ebc09c36SJim Ingham                 }
81ebc09c36SJim Ingham 
82ebc09c36SJim Ingham                 if (commands.size() > 0)
83ebc09c36SJim Ingham                 {
84ebc09c36SJim Ingham                     const size_t num_commands = commands.size();
85ebc09c36SJim Ingham                     size_t i;
86ebc09c36SJim Ingham                     for (i = 0; i<num_commands; ++i)
87ebc09c36SJim Ingham                     {
88a7015092SGreg Clayton                         result.GetOutputStream().Printf ("%s %s\n",
89a7015092SGreg Clayton                                                          m_interpreter.GetPrompt(),
90a7015092SGreg Clayton                                                          commands[i].c_str());
91a7015092SGreg Clayton                         if (!m_interpreter.HandleCommand(commands[i].c_str(), false, result))
92ebc09c36SJim Ingham                             break;
93ebc09c36SJim Ingham                     }
94ebc09c36SJim Ingham 
95ebc09c36SJim Ingham                     if (i < num_commands)
96ebc09c36SJim Ingham                     {
97ebc09c36SJim Ingham                         result.AppendErrorWithFormat("Aborting source of '%s' after command '%s' failed.\n",
98ebc09c36SJim Ingham                                                      filename, commands[i].c_str());
99ebc09c36SJim Ingham                         result.SetStatus (eReturnStatusSuccessFinishResult);
100ebc09c36SJim Ingham                     }
101ebc09c36SJim Ingham                     else
102ebc09c36SJim Ingham                     {
103ebc09c36SJim Ingham                         success = true;
104ebc09c36SJim Ingham                         result.SetStatus (eReturnStatusFailed);
105ebc09c36SJim Ingham                     }
106ebc09c36SJim Ingham                 }
107ebc09c36SJim Ingham             }
108ebc09c36SJim Ingham             else
109ebc09c36SJim Ingham             {
110ebc09c36SJim Ingham                 result.AppendErrorWithFormat ("File '%s' does not exist.\n", filename);
111ebc09c36SJim Ingham                 result.SetStatus (eReturnStatusFailed);
112ebc09c36SJim Ingham                 success = false;
113ebc09c36SJim Ingham             }
114ebc09c36SJim Ingham 
115ebc09c36SJim Ingham             if (success)
116ebc09c36SJim Ingham             {
117ebc09c36SJim Ingham                 result.SetStatus (eReturnStatusSuccessFinishNoResult);
118ebc09c36SJim Ingham             }
119ebc09c36SJim Ingham         }
120ebc09c36SJim Ingham         else
121ebc09c36SJim Ingham         {
122ebc09c36SJim Ingham             result.AppendErrorWithFormat("'%s' takes exactly one executable filename argument.\n", GetCommandName());
123ebc09c36SJim Ingham             result.SetStatus (eReturnStatusFailed);
124ebc09c36SJim Ingham         }
125ebc09c36SJim Ingham         return result.Succeeded();
126ebc09c36SJim Ingham 
127ebc09c36SJim Ingham     }
128ebc09c36SJim Ingham };
129ebc09c36SJim Ingham 
130ebc09c36SJim Ingham #pragma mark CommandObjectCommandsAlias
131ebc09c36SJim Ingham //-------------------------------------------------------------------------
132ebc09c36SJim Ingham // CommandObjectCommandsAlias
133ebc09c36SJim Ingham //-------------------------------------------------------------------------
134ebc09c36SJim Ingham 
135ebc09c36SJim Ingham class CommandObjectCommandsAlias : public CommandObject
136ebc09c36SJim Ingham {
137ebc09c36SJim Ingham public:
138a7015092SGreg Clayton     CommandObjectCommandsAlias (CommandInterpreter &interpreter) :
139a7015092SGreg Clayton         CommandObject (interpreter,
140a7015092SGreg Clayton                        "commands alias",
141e3d26315SCaroline Tice                        "Allow users to define their own debugger command abbreviations.",
1420708e2c2SSean Callanan                        "commands alias <new_command> <old_command> [<options-for-aliased-command>]")
143ebc09c36SJim Ingham     {
144ebc09c36SJim Ingham         SetHelpLong(
145ebc09c36SJim Ingham     "'alias' allows the user to create a short-cut or abbreviation for long \n\
146ebc09c36SJim Ingham     commands, multi-word commands, and commands that take particular options. \n\
147ebc09c36SJim Ingham     Below are some simple examples of how one might use the 'alias' command: \n\
14809799af6SCaroline Tice     \n    'commands alias sc script'           // Creates the abbreviation 'sc' for the 'script' \n\
149ebc09c36SJim Ingham                                          // command. \n\
15009799af6SCaroline Tice     'commands alias bp breakpoint'       // Creates the abbreviation 'bp' for the 'breakpoint' \n\
151ebc09c36SJim Ingham                                          // command.  Since breakpoint commands are two-word \n\
152ebc09c36SJim Ingham                                          // commands, the user will still need to enter the \n\
153ebc09c36SJim Ingham                                          // second word after 'bp', e.g. 'bp enable' or \n\
154ebc09c36SJim Ingham                                          // 'bp delete'. \n\
15509799af6SCaroline Tice     'commands alias bpl breakpoint list' // Creates the abbreviation 'bpl' for the \n\
156ebc09c36SJim Ingham                                          // two-word command 'breakpoint list'. \n\
157ebc09c36SJim Ingham     \nAn alias can include some options for the command, with the values either \n\
158ebc09c36SJim Ingham     filled in at the time the alias is created, or specified as positional \n\
159ebc09c36SJim Ingham     arguments, to be filled in when the alias is invoked.  The following example \n\
160ebc09c36SJim Ingham     shows how to create aliases with options: \n\
161ebc09c36SJim Ingham     \n\
16209799af6SCaroline Tice     'commands alias bfl breakpoint set -f %1 -l %2' \n\
163ebc09c36SJim Ingham     \nThis creates the abbreviation 'bfl' (for break-file-line), with the -f and -l \n\
164ebc09c36SJim Ingham     options already part of the alias.  So if the user wants to set a breakpoint \n\
165ebc09c36SJim Ingham     by file and line without explicitly having to use the -f and -l options, the \n\
166ebc09c36SJim Ingham     user can now use 'bfl' instead.  The '%1' and '%2' are positional placeholders \n\
167ebc09c36SJim Ingham     for the actual arguments that will be passed when the alias command is used. \n\
168ebc09c36SJim Ingham     The number in the placeholder refers to the position/order the actual value \n\
169ebc09c36SJim Ingham     occupies when the alias is used.  So all the occurrences of '%1' in the alias \n\
170ebc09c36SJim Ingham     will be replaced with the first argument, all the occurrences of '%2' in the \n\
171ebc09c36SJim Ingham     alias will be replaced with the second argument, and so on.  This also allows \n\
172ebc09c36SJim Ingham     actual arguments to be used multiple times within an alias (see 'process \n\
173ebc09c36SJim Ingham     launch' example below).  So in the 'bfl' case, the actual file value will be \n\
174ebc09c36SJim Ingham     filled in with the first argument following 'bfl' and the actual line number \n\
175ebc09c36SJim Ingham     value will be filled in with the second argument.  The user would use this \n\
176ebc09c36SJim Ingham     alias as follows: \n\
17709799af6SCaroline Tice     \n    (lldb)  commands alias bfl breakpoint set -f %1 -l %2 \n\
178ebc09c36SJim Ingham     <... some time later ...> \n\
17909799af6SCaroline Tice     (lldb)  bfl my-file.c 137 \n\
180ebc09c36SJim Ingham     \nThis would be the same as if the user had entered \n\
181ebc09c36SJim Ingham     'breakpoint set -f my-file.c -l 137'. \n\
182ebc09c36SJim Ingham     \nAnother example: \n\
18309799af6SCaroline Tice     \n    (lldb)  commands alias pltty  process launch -s -o %1 -e %1 \n\
18409799af6SCaroline Tice     (lldb)  pltty /dev/tty0 \n\
185ebc09c36SJim Ingham            // becomes 'process launch -s -o /dev/tty0 -e /dev/tty0' \n\
186ebc09c36SJim Ingham     \nIf the user always wanted to pass the same value to a particular option, the \n\
187ebc09c36SJim Ingham     alias could be defined with that value directly in the alias as a constant, \n\
188ebc09c36SJim Ingham     rather than using a positional placeholder: \n\
1890708e2c2SSean Callanan     \n    commands alias bl3  breakpoint set -f %1 -l 3  // Always sets a breakpoint on line \n\
190ebc09c36SJim Ingham                                                    // 3 of whatever file is indicated. \n");
191ebc09c36SJim Ingham 
192ebc09c36SJim Ingham     }
193ebc09c36SJim Ingham 
194ebc09c36SJim Ingham     ~CommandObjectCommandsAlias ()
195ebc09c36SJim Ingham     {
196ebc09c36SJim Ingham     }
197ebc09c36SJim Ingham 
198ebc09c36SJim Ingham 
199ebc09c36SJim Ingham     bool
200ebc09c36SJim Ingham     Execute
201ebc09c36SJim Ingham     (
202ebc09c36SJim Ingham         Args& args,
203ebc09c36SJim Ingham         CommandReturnObject &result
204ebc09c36SJim Ingham     )
205ebc09c36SJim Ingham     {
206867b185dSCaroline Tice         size_t argc = args.GetArgumentCount();
207ebc09c36SJim Ingham 
208ebc09c36SJim Ingham         if (argc < 2)
209ebc09c36SJim Ingham         {
210ebc09c36SJim Ingham             result.AppendError ("'alias' requires at least two arguments");
211ebc09c36SJim Ingham             result.SetStatus (eReturnStatusFailed);
212ebc09c36SJim Ingham             return false;
213ebc09c36SJim Ingham         }
214ebc09c36SJim Ingham 
215ebc09c36SJim Ingham         const std::string alias_command = args.GetArgumentAtIndex(0);
216ebc09c36SJim Ingham         const std::string actual_command = args.GetArgumentAtIndex(1);
217ebc09c36SJim Ingham 
218ebc09c36SJim Ingham         args.Shift();  // Shift the alias command word off the argument vector.
219ebc09c36SJim Ingham         args.Shift();  // Shift the old command word off the argument vector.
220ebc09c36SJim Ingham 
221ebc09c36SJim Ingham         // Verify that the command is alias'able, and get the appropriate command object.
222ebc09c36SJim Ingham 
223a7015092SGreg Clayton         if (m_interpreter.CommandExists (alias_command.c_str()))
224ebc09c36SJim Ingham         {
225ebc09c36SJim Ingham             result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be redefined.\n",
226ebc09c36SJim Ingham                                          alias_command.c_str());
227ebc09c36SJim Ingham             result.SetStatus (eReturnStatusFailed);
228ebc09c36SJim Ingham         }
229ebc09c36SJim Ingham         else
230ebc09c36SJim Ingham         {
231a7015092SGreg Clayton              CommandObjectSP command_obj_sp(m_interpreter.GetCommandSPExact (actual_command.c_str(), true));
232ebc09c36SJim Ingham              CommandObjectSP subcommand_obj_sp;
233ebc09c36SJim Ingham              bool use_subcommand = false;
234ebc09c36SJim Ingham              if (command_obj_sp.get())
235ebc09c36SJim Ingham              {
236ebc09c36SJim Ingham                  CommandObject *cmd_obj = command_obj_sp.get();
237c982c768SGreg Clayton                  CommandObject *sub_cmd_obj = NULL;
238ebc09c36SJim Ingham                  OptionArgVectorSP option_arg_vector_sp = OptionArgVectorSP (new OptionArgVector);
239ebc09c36SJim Ingham                  OptionArgVector *option_arg_vector = option_arg_vector_sp.get();
240ebc09c36SJim Ingham 
241ebc09c36SJim Ingham                  if (cmd_obj->IsMultiwordObject())
242ebc09c36SJim Ingham                  {
243ebc09c36SJim Ingham                      if (argc >= 3)
244ebc09c36SJim Ingham                      {
245ebc09c36SJim Ingham                          const std::string sub_command = args.GetArgumentAtIndex(0);
246ebc09c36SJim Ingham                          assert (sub_command.length() != 0);
247ebc09c36SJim Ingham                          subcommand_obj_sp =
248ebc09c36SJim Ingham                                            (((CommandObjectMultiword *) cmd_obj)->GetSubcommandSP (sub_command.c_str()));
249ebc09c36SJim Ingham                          if (subcommand_obj_sp.get())
250ebc09c36SJim Ingham                          {
251ebc09c36SJim Ingham                              sub_cmd_obj = subcommand_obj_sp.get();
252ebc09c36SJim Ingham                              use_subcommand = true;
253ebc09c36SJim Ingham                              args.Shift();  // Shift the sub_command word off the argument vector.
254ebc09c36SJim Ingham                          }
255ebc09c36SJim Ingham                          else
256ebc09c36SJim Ingham                          {
257ebc09c36SJim Ingham                              result.AppendErrorWithFormat ("Error occurred while attempting to look up command '%s %s'.\n",
258ebc09c36SJim Ingham                                                           alias_command.c_str(), sub_command.c_str());
259ebc09c36SJim Ingham                              result.SetStatus (eReturnStatusFailed);
260ebc09c36SJim Ingham                              return false;
261ebc09c36SJim Ingham                          }
262ebc09c36SJim Ingham                      }
263ebc09c36SJim Ingham                  }
264ebc09c36SJim Ingham 
265ebc09c36SJim Ingham                  // Verify & handle any options/arguments passed to the alias command
266ebc09c36SJim Ingham 
267ebc09c36SJim Ingham                  if (args.GetArgumentCount () > 0)
268ebc09c36SJim Ingham                  {
269ebc09c36SJim Ingham                      if ((!use_subcommand && (cmd_obj->WantsRawCommandString()))
270ebc09c36SJim Ingham                          || (use_subcommand && (sub_cmd_obj->WantsRawCommandString())))
271ebc09c36SJim Ingham                      {
272ebc09c36SJim Ingham                          result.AppendErrorWithFormat ("'%s' cannot be aliased with any options or arguments.\n",
273ebc09c36SJim Ingham                                                       (use_subcommand ? sub_cmd_obj->GetCommandName()
274ebc09c36SJim Ingham                                                                       : cmd_obj->GetCommandName()));
275ebc09c36SJim Ingham                          result.SetStatus (eReturnStatusFailed);
276ebc09c36SJim Ingham                          return false;
277ebc09c36SJim Ingham                      }
278ebc09c36SJim Ingham 
279ebc09c36SJim Ingham                      // options or arguments have been passed to the alias command, and must be
280ebc09c36SJim Ingham                      // verified & processed here.
281ebc09c36SJim Ingham                      if ((!use_subcommand && (cmd_obj->GetOptions() != NULL))
282ebc09c36SJim Ingham                          || (use_subcommand && (sub_cmd_obj->GetOptions() != NULL)))
283ebc09c36SJim Ingham                      {
284ebc09c36SJim Ingham                          Options *options;
285ebc09c36SJim Ingham                          if (use_subcommand)
286ebc09c36SJim Ingham                              options = sub_cmd_obj->GetOptions();
287ebc09c36SJim Ingham                          else
288ebc09c36SJim Ingham                              options = cmd_obj->GetOptions();
289ebc09c36SJim Ingham                          options->ResetOptionValues ();
290ebc09c36SJim Ingham                          args.Unshift ("dummy_arg");
291ebc09c36SJim Ingham                          args.ParseAliasOptions (*options, result, option_arg_vector);
292ebc09c36SJim Ingham                          args.Shift ();
293ebc09c36SJim Ingham                          if (result.Succeeded())
294ebc09c36SJim Ingham                              options->VerifyPartialOptions (result);
295867b185dSCaroline Tice                          if (!result.Succeeded() && result.GetStatus() != lldb::eReturnStatusStarted)
296ebc09c36SJim Ingham                         {
297867b185dSCaroline Tice                             result.AppendError ("Unable to create requested command alias.\n");
298867b185dSCaroline Tice                         }
299867b185dSCaroline Tice                      }
300867b185dSCaroline Tice 
301867b185dSCaroline Tice                      // Anything remaining in args must be a plain argument.
302867b185dSCaroline Tice 
303867b185dSCaroline Tice                      argc = args.GetArgumentCount();
304c982c768SGreg Clayton                      for (size_t i = 0; i < argc; ++i)
305ebc09c36SJim Ingham                          option_arg_vector->push_back (OptionArgPair ("<argument>",
306ebc09c36SJim Ingham                                                                       std::string (args.GetArgumentAtIndex (i))));
307ebc09c36SJim Ingham                  }
308ebc09c36SJim Ingham 
309ebc09c36SJim Ingham                  // Create the alias.
310ebc09c36SJim Ingham 
311a7015092SGreg Clayton                  if (m_interpreter.AliasExists (alias_command.c_str())
312a7015092SGreg Clayton                      || m_interpreter.UserCommandExists (alias_command.c_str()))
313ebc09c36SJim Ingham                  {
314a7015092SGreg Clayton                      OptionArgVectorSP tmp_option_arg_sp (m_interpreter.GetAliasOptions (alias_command.c_str()));
315ebc09c36SJim Ingham                      if (tmp_option_arg_sp.get())
316ebc09c36SJim Ingham                      {
317ebc09c36SJim Ingham                          if (option_arg_vector->size() == 0)
318a7015092SGreg Clayton                              m_interpreter.RemoveAliasOptions (alias_command.c_str());
319ebc09c36SJim Ingham                      }
320ebc09c36SJim Ingham                      result.AppendWarningWithFormat ("Overwriting existing definition for '%s'.\n",
321ebc09c36SJim Ingham                                                      alias_command.c_str());
322ebc09c36SJim Ingham                  }
323ebc09c36SJim Ingham 
324ebc09c36SJim Ingham                  if (use_subcommand)
325a7015092SGreg Clayton                      m_interpreter.AddAlias (alias_command.c_str(), subcommand_obj_sp);
326ebc09c36SJim Ingham                  else
327a7015092SGreg Clayton                      m_interpreter.AddAlias (alias_command.c_str(), command_obj_sp);
328ebc09c36SJim Ingham                  if (option_arg_vector->size() > 0)
329a7015092SGreg Clayton                      m_interpreter.AddOrReplaceAliasOptions (alias_command.c_str(), option_arg_vector_sp);
330ebc09c36SJim Ingham                  result.SetStatus (eReturnStatusSuccessFinishNoResult);
331ebc09c36SJim Ingham              }
332ebc09c36SJim Ingham              else
333ebc09c36SJim Ingham              {
334ebc09c36SJim Ingham                  result.AppendErrorWithFormat ("'%s' is not an existing command.\n", actual_command.c_str());
335ebc09c36SJim Ingham                  result.SetStatus (eReturnStatusFailed);
336ebc09c36SJim Ingham              }
337ebc09c36SJim Ingham         }
338ebc09c36SJim Ingham 
339ebc09c36SJim Ingham         return result.Succeeded();
340ebc09c36SJim Ingham     }
341ebc09c36SJim Ingham };
342ebc09c36SJim Ingham 
343ebc09c36SJim Ingham #pragma mark CommandObjectCommandsUnalias
344ebc09c36SJim Ingham //-------------------------------------------------------------------------
345ebc09c36SJim Ingham // CommandObjectCommandsUnalias
346ebc09c36SJim Ingham //-------------------------------------------------------------------------
347ebc09c36SJim Ingham 
348ebc09c36SJim Ingham class CommandObjectCommandsUnalias : public CommandObject
349ebc09c36SJim Ingham {
350ebc09c36SJim Ingham public:
351a7015092SGreg Clayton     CommandObjectCommandsUnalias (CommandInterpreter &interpreter) :
352a7015092SGreg Clayton         CommandObject (interpreter,
353a7015092SGreg Clayton                        "commands unalias",
35486ddae50SCaroline Tice                        "Allow the user to remove/delete a user-defined command abbreviation.",
355ebc09c36SJim Ingham                        "unalias <alias-name-to-be-removed>")
356ebc09c36SJim Ingham     {
357ebc09c36SJim Ingham     }
358ebc09c36SJim Ingham 
359ebc09c36SJim Ingham     ~CommandObjectCommandsUnalias()
360ebc09c36SJim Ingham     {
361ebc09c36SJim Ingham     }
362ebc09c36SJim Ingham 
363ebc09c36SJim Ingham 
364ebc09c36SJim Ingham     bool
365ebc09c36SJim Ingham     Execute
366ebc09c36SJim Ingham     (
367ebc09c36SJim Ingham         Args& args,
368ebc09c36SJim Ingham         CommandReturnObject &result
369ebc09c36SJim Ingham     )
370ebc09c36SJim Ingham     {
371ebc09c36SJim Ingham         CommandObject::CommandMap::iterator pos;
372ebc09c36SJim Ingham         CommandObject *cmd_obj;
373ebc09c36SJim Ingham 
374ebc09c36SJim Ingham         if (args.GetArgumentCount() != 0)
375ebc09c36SJim Ingham         {
376ebc09c36SJim Ingham             const char *command_name = args.GetArgumentAtIndex(0);
377a7015092SGreg Clayton             cmd_obj = m_interpreter.GetCommandObject(command_name);
378ebc09c36SJim Ingham             if (cmd_obj)
379ebc09c36SJim Ingham             {
380a7015092SGreg Clayton                 if (m_interpreter.CommandExists (command_name))
381ebc09c36SJim Ingham                 {
382ebc09c36SJim Ingham                     result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be removed.\n",
383ebc09c36SJim Ingham                                                   command_name);
384ebc09c36SJim Ingham                     result.SetStatus (eReturnStatusFailed);
385ebc09c36SJim Ingham                 }
386ebc09c36SJim Ingham                 else
387ebc09c36SJim Ingham                 {
388ebc09c36SJim Ingham 
389a7015092SGreg Clayton                     if (m_interpreter.RemoveAlias (command_name) == false)
390ebc09c36SJim Ingham                     {
391a7015092SGreg Clayton                         if (m_interpreter.AliasExists (command_name))
392ebc09c36SJim Ingham                             result.AppendErrorWithFormat ("Error occurred while attempting to unalias '%s'.\n",
393ebc09c36SJim Ingham                                                           command_name);
394ebc09c36SJim Ingham                         else
395ebc09c36SJim Ingham                             result.AppendErrorWithFormat ("'%s' is not an existing alias.\n", command_name);
396ebc09c36SJim Ingham                         result.SetStatus (eReturnStatusFailed);
397ebc09c36SJim Ingham                     }
398ebc09c36SJim Ingham                     else
399ebc09c36SJim Ingham                         result.SetStatus (eReturnStatusSuccessFinishNoResult);
400ebc09c36SJim Ingham                 }
401ebc09c36SJim Ingham             }
402ebc09c36SJim Ingham             else
403ebc09c36SJim Ingham             {
404ebc09c36SJim Ingham                 result.AppendErrorWithFormat ("'%s' is not a known command.\nTry 'help' to see a "
405ebc09c36SJim Ingham                                               "current list of commands.\n",
406ebc09c36SJim Ingham                                              command_name);
407ebc09c36SJim Ingham                 result.SetStatus (eReturnStatusFailed);
408ebc09c36SJim Ingham             }
409ebc09c36SJim Ingham         }
410ebc09c36SJim Ingham         else
411ebc09c36SJim Ingham         {
412ebc09c36SJim Ingham             result.AppendError ("must call 'unalias' with a valid alias");
413ebc09c36SJim Ingham             result.SetStatus (eReturnStatusFailed);
414ebc09c36SJim Ingham         }
415ebc09c36SJim Ingham 
416ebc09c36SJim Ingham         return result.Succeeded();
417ebc09c36SJim Ingham     }
418ebc09c36SJim Ingham };
419ebc09c36SJim Ingham 
420ebc09c36SJim Ingham #pragma mark CommandObjectMultiwordCommands
421ebc09c36SJim Ingham 
422ebc09c36SJim Ingham //-------------------------------------------------------------------------
423ebc09c36SJim Ingham // CommandObjectMultiwordCommands
424ebc09c36SJim Ingham //-------------------------------------------------------------------------
425ebc09c36SJim Ingham 
426ebc09c36SJim Ingham CommandObjectMultiwordCommands::CommandObjectMultiwordCommands (CommandInterpreter &interpreter) :
427a7015092SGreg Clayton     CommandObjectMultiword (interpreter,
428a7015092SGreg Clayton                             "commands",
4293f4c09c1SCaroline Tice                             "A set of commands for managing or customizing the debugger commands.",
430ebc09c36SJim Ingham                             "commands <subcommand> [<subcommand-options>]")
431ebc09c36SJim Ingham {
432a7015092SGreg Clayton     LoadSubCommand ("source",  CommandObjectSP (new CommandObjectCommandsSource (interpreter)));
433a7015092SGreg Clayton     LoadSubCommand ("alias",   CommandObjectSP (new CommandObjectCommandsAlias (interpreter)));
434a7015092SGreg Clayton     LoadSubCommand ("unalias", CommandObjectSP (new CommandObjectCommandsUnalias (interpreter)));
435ebc09c36SJim Ingham }
436ebc09c36SJim Ingham 
437ebc09c36SJim Ingham CommandObjectMultiwordCommands::~CommandObjectMultiwordCommands ()
438ebc09c36SJim Ingham {
439ebc09c36SJim Ingham }
440ebc09c36SJim Ingham 
441