1 //===-- CommandAlias.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 "lldb/Interpreter/CommandAlias.h"
11 
12 #include "lldb/Core/StreamString.h"
13 #include "lldb/Interpreter/CommandObject.h"
14 #include "lldb/Interpreter/CommandReturnObject.h"
15 #include "lldb/Interpreter/Options.h"
16 
17 using namespace lldb;
18 using namespace lldb_private;
19 
20 static bool
21 ProcessAliasOptionsArgs (lldb::CommandObjectSP &cmd_obj_sp,
22                          const char *options_args,
23                          OptionArgVectorSP &option_arg_vector_sp)
24 {
25     bool success = true;
26     OptionArgVector *option_arg_vector = option_arg_vector_sp.get();
27 
28     if (!options_args || (strlen (options_args) < 1))
29         return true;
30 
31     std::string options_string (options_args);
32     Args args (options_args);
33     CommandReturnObject result;
34     // Check to see if the command being aliased can take any command options.
35     Options *options = cmd_obj_sp->GetOptions ();
36     if (options)
37     {
38         // See if any options were specified as part of the alias;  if so, handle them appropriately.
39         options->NotifyOptionParsingStarting ();
40         args.Unshift ("dummy_arg");
41         args.ParseAliasOptions (*options, result, option_arg_vector, options_string);
42         args.Shift ();
43         if (result.Succeeded())
44             options->VerifyPartialOptions (result);
45         if (!result.Succeeded() && result.GetStatus() != lldb::eReturnStatusStarted)
46         {
47             result.AppendError ("Unable to create requested alias.\n");
48             return false;
49         }
50     }
51 
52     if (!options_string.empty())
53     {
54         if (cmd_obj_sp->WantsRawCommandString ())
55             option_arg_vector->push_back (OptionArgPair ("<argument>",
56                                                          OptionArgValue (-1,
57                                                                          options_string)));
58         else
59         {
60             const size_t argc = args.GetArgumentCount();
61             for (size_t i = 0; i < argc; ++i)
62                 if (strcmp (args.GetArgumentAtIndex (i), "") != 0)
63                     option_arg_vector->push_back
64                     (OptionArgPair ("<argument>",
65                                     OptionArgValue (-1,
66                                                     std::string (args.GetArgumentAtIndex (i)))));
67         }
68     }
69 
70     return success;
71 }
72 
73 CommandAlias::UniquePointer
74 CommandAlias::GetCommandAlias (lldb::CommandObjectSP cmd_sp,
75                                const char *options_args)
76 {
77     CommandAlias::UniquePointer ret_val(nullptr);
78     OptionArgVectorSP opt_args_sp(new OptionArgVector);
79     if (ProcessAliasOptionsArgs(cmd_sp, options_args, opt_args_sp))
80         ret_val.reset(new CommandAlias(cmd_sp, opt_args_sp));
81     return ret_val;
82 }
83 
84 CommandAlias::CommandAlias (lldb::CommandObjectSP cmd_sp,
85                             OptionArgVectorSP args_sp) :
86 m_underlying_command_sp(cmd_sp),
87 m_option_args_sp(args_sp)
88 {
89 }
90 
91 void
92 CommandAlias::GetAliasExpansion (StreamString &help_string)
93 {
94     const char* command_name = m_underlying_command_sp->GetCommandName();
95     help_string.Printf ("'%s", command_name);
96 
97     if (m_option_args_sp)
98     {
99         OptionArgVector *options = m_option_args_sp.get();
100         for (size_t i = 0; i < options->size(); ++i)
101         {
102             OptionArgPair cur_option = (*options)[i];
103             std::string opt = cur_option.first;
104             OptionArgValue value_pair = cur_option.second;
105             std::string value = value_pair.second;
106             if (opt.compare("<argument>") == 0)
107             {
108                 help_string.Printf (" %s", value.c_str());
109             }
110             else
111             {
112                 help_string.Printf (" %s", opt.c_str());
113                 if ((value.compare ("<no-argument>") != 0)
114                     && (value.compare ("<need-argument") != 0))
115                 {
116                     help_string.Printf (" %s", value.c_str());
117                 }
118             }
119         }
120     }
121 
122     help_string.Printf ("'");
123 }
124