1 // Copyright 2010 The Kyua Authors. 2 // All rights reserved. 3 // 4 // Redistribution and use in source and binary forms, with or without 5 // modification, are permitted provided that the following conditions are 6 // met: 7 // 8 // * Redistributions of source code must retain the above copyright 9 // notice, this list of conditions and the following disclaimer. 10 // * Redistributions in binary form must reproduce the above copyright 11 // notice, this list of conditions and the following disclaimer in the 12 // documentation and/or other materials provided with the distribution. 13 // * Neither the name of Google Inc. nor the names of its contributors 14 // may be used to endorse or promote products derived from this software 15 // without specific prior written permission. 16 // 17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 29 #include "utils/cmdline/base_command.hpp" 30 31 #include "utils/cmdline/exceptions.hpp" 32 #include "utils/cmdline/options.hpp" 33 #include "utils/cmdline/parser.ipp" 34 #include "utils/sanity.hpp" 35 36 namespace cmdline = utils::cmdline; 37 38 39 /// Creates a new command. 40 /// 41 /// \param name_ The name of the command. Must be unique within the context of 42 /// a program and have no spaces. 43 /// \param arg_list_ A textual description of the arguments received by the 44 /// command. May be empty. 45 /// \param min_args_ The minimum number of arguments required by the command. 46 /// \param max_args_ The maximum number of arguments required by the command. 47 /// -1 means infinity. 48 /// \param short_description_ A description of the purpose of the command. 49 cmdline::command_proto::command_proto(const std::string& name_, 50 const std::string& arg_list_, 51 const int min_args_, 52 const int max_args_, 53 const std::string& short_description_) : 54 _name(name_), 55 _arg_list(arg_list_), 56 _min_args(min_args_), 57 _max_args(max_args_), 58 _short_description(short_description_) 59 { 60 PRE(name_.find(' ') == std::string::npos); 61 PRE(max_args_ == -1 || min_args_ <= max_args_); 62 } 63 64 65 /// Destructor for a command. 66 cmdline::command_proto::~command_proto(void) 67 { 68 for (options_vector::const_iterator iter = _options.begin(); 69 iter != _options.end(); iter++) 70 delete *iter; 71 } 72 73 74 /// Internal method to register a dynamically-allocated option. 75 /// 76 /// Always use add_option() from subclasses to add options. 77 /// 78 /// \param option_ The option to add. Must have been dynamically allocated. 79 /// This grabs ownership of the pointer, which is released when the command 80 /// is destroyed. 81 void 82 cmdline::command_proto::add_option_ptr(const cmdline::base_option* option_) 83 { 84 try { 85 _options.push_back(option_); 86 } catch (...) { 87 delete option_; 88 throw; 89 } 90 } 91 92 93 /// Processes the command line based on the command description. 94 /// 95 /// \param args The raw command line to be processed. 96 /// 97 /// \return An object containing the list of options and free arguments found in 98 /// args. 99 /// 100 /// \throw cmdline::usage_error If there is a problem processing the command 101 /// line. This error is caused by invalid input from the user. 102 cmdline::parsed_cmdline 103 cmdline::command_proto::parse_cmdline(const cmdline::args_vector& args) const 104 { 105 PRE(name() == args[0]); 106 const parsed_cmdline cmdline = cmdline::parse(args, options()); 107 108 const int argc = cmdline.arguments().size(); 109 if (argc < _min_args) 110 throw usage_error("Not enough arguments"); 111 if (_max_args != -1 && argc > _max_args) 112 throw usage_error("Too many arguments"); 113 114 return cmdline; 115 } 116 117 118 /// Gets the name of the command. 119 /// 120 /// \return The command name. 121 const std::string& 122 cmdline::command_proto::name(void) const 123 { 124 return _name; 125 } 126 127 128 /// Gets the textual representation of the arguments list. 129 /// 130 /// \return The description of the arguments list. 131 const std::string& 132 cmdline::command_proto::arg_list(void) const 133 { 134 return _arg_list; 135 } 136 137 138 /// Gets the description of the purpose of the command. 139 /// 140 /// \return The description of the command. 141 const std::string& 142 cmdline::command_proto::short_description(void) const 143 { 144 return _short_description; 145 } 146 147 148 /// Gets the definition of the options accepted by the command. 149 /// 150 /// \return The list of options. 151 const cmdline::options_vector& 152 cmdline::command_proto::options(void) const 153 { 154 return _options; 155 } 156 157 158 /// Creates a new command. 159 /// 160 /// \param name_ The name of the command. Must be unique within the context of 161 /// a program and have no spaces. 162 /// \param arg_list_ A textual description of the arguments received by the 163 /// command. May be empty. 164 /// \param min_args_ The minimum number of arguments required by the command. 165 /// \param max_args_ The maximum number of arguments required by the command. 166 /// -1 means infinity. 167 /// \param short_description_ A description of the purpose of the command. 168 cmdline::base_command_no_data::base_command_no_data( 169 const std::string& name_, 170 const std::string& arg_list_, 171 const int min_args_, 172 const int max_args_, 173 const std::string& short_description_) : 174 command_proto(name_, arg_list_, min_args_, max_args_, short_description_) 175 { 176 } 177 178 179 /// Entry point for the command. 180 /// 181 /// This delegates execution to the run() abstract function after the command 182 /// line provided in args has been parsed. 183 /// 184 /// If this function returns, the command is assumed to have been executed 185 /// successfully. Any error must be reported by means of exceptions. 186 /// 187 /// \param ui Object to interact with the I/O of the command. The command must 188 /// always use this object to write to stdout and stderr. 189 /// \param args The command line passed to the command broken by word, which 190 /// includes options and arguments. 191 /// 192 /// \return The exit code that the program has to return. 0 on success, some 193 /// other value on error. 194 /// \throw usage_error If args is invalid (i.e. if the options are mispecified 195 /// or if the arguments are invalid). 196 int 197 cmdline::base_command_no_data::main(cmdline::ui* ui, 198 const cmdline::args_vector& args) 199 { 200 return run(ui, parse_cmdline(args)); 201 } 202