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