1 // Copyright 2010 Google Inc. 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/sanity.hpp" 34 35 namespace cmdline = utils::cmdline; 36 37 38 /// Creates a new command. 39 /// 40 /// \param name_ The name of the command. Must be unique within the context of 41 /// a program and have no spaces. 42 /// \param arg_list_ A textual description of the arguments received by the 43 /// command. May be empty. 44 /// \param min_args_ The minimum number of arguments required by the command. 45 /// \param max_args_ The maximum number of arguments required by the command. 46 /// -1 means infinity. 47 /// \param short_description_ A description of the purpose of the command. 48 cmdline::command_proto::command_proto(const std::string& name_, 49 const std::string& arg_list_, 50 const int min_args_, 51 const int max_args_, 52 const std::string& short_description_) : 53 _name(name_), 54 _arg_list(arg_list_), 55 _min_args(min_args_), 56 _max_args(max_args_), 57 _short_description(short_description_) 58 { 59 PRE(name_.find(' ') == std::string::npos); 60 PRE(max_args_ == -1 || min_args_ <= max_args_); 61 } 62 63 64 /// Destructor for a command. 65 cmdline::command_proto::~command_proto(void) 66 { 67 for (options_vector::const_iterator iter = _options.begin(); 68 iter != _options.end(); iter++) 69 delete *iter; 70 } 71 72 73 /// Internal method to register a dynamically-allocated option. 74 /// 75 /// Always use add_option() from subclasses to add options. 76 /// 77 /// \param option_ The option to add. Must have been dynamically allocated. 78 /// This grabs ownership of the pointer, which is released when the command 79 /// is destroyed. 80 void 81 cmdline::command_proto::add_option_ptr(const cmdline::base_option* option_) 82 { 83 try { 84 _options.push_back(option_); 85 } catch (...) { 86 delete option_; 87 throw; 88 } 89 } 90 91 92 /// Processes the command line based on the command description. 93 /// 94 /// \param args The raw command line to be processed. 95 /// 96 /// \return An object containing the list of options and free arguments found in 97 /// args. 98 /// 99 /// \throw cmdline::usage_error If there is a problem processing the command 100 /// line. This error is caused by invalid input from the user. 101 cmdline::parsed_cmdline 102 cmdline::command_proto::parse_cmdline(const cmdline::args_vector& args) const 103 { 104 PRE(name() == args[0]); 105 const parsed_cmdline cmdline = cmdline::parse(args, options()); 106 107 const int argc = cmdline.arguments().size(); 108 if (argc < _min_args) 109 throw usage_error("Not enough arguments"); 110 if (_max_args != -1 && argc > _max_args) 111 throw usage_error("Too many arguments"); 112 113 return cmdline; 114 } 115 116 117 /// Gets the name of the command. 118 /// 119 /// \return The command name. 120 const std::string& 121 cmdline::command_proto::name(void) const 122 { 123 return _name; 124 } 125 126 127 /// Gets the textual representation of the arguments list. 128 /// 129 /// \return The description of the arguments list. 130 const std::string& 131 cmdline::command_proto::arg_list(void) const 132 { 133 return _arg_list; 134 } 135 136 137 /// Gets the description of the purpose of the command. 138 /// 139 /// \return The description of the command. 140 const std::string& 141 cmdline::command_proto::short_description(void) const 142 { 143 return _short_description; 144 } 145 146 147 /// Gets the definition of the options accepted by the command. 148 /// 149 /// \return The list of options. 150 const cmdline::options_vector& 151 cmdline::command_proto::options(void) const 152 { 153 return _options; 154 } 155 156 157 /// Creates a new command. 158 /// 159 /// \param name_ The name of the command. Must be unique within the context of 160 /// a program and have no spaces. 161 /// \param arg_list_ A textual description of the arguments received by the 162 /// command. May be empty. 163 /// \param min_args_ The minimum number of arguments required by the command. 164 /// \param max_args_ The maximum number of arguments required by the command. 165 /// -1 means infinity. 166 /// \param short_description_ A description of the purpose of the command. 167 cmdline::base_command_no_data::base_command_no_data( 168 const std::string& name_, 169 const std::string& arg_list_, 170 const int min_args_, 171 const int max_args_, 172 const std::string& short_description_) : 173 command_proto(name_, arg_list_, min_args_, max_args_, short_description_) 174 { 175 } 176 177 178 /// Entry point for the command. 179 /// 180 /// This delegates execution to the run() abstract function after the command 181 /// line provided in args has been parsed. 182 /// 183 /// If this function returns, the command is assumed to have been executed 184 /// successfully. Any error must be reported by means of exceptions. 185 /// 186 /// \param ui Object to interact with the I/O of the command. The command must 187 /// always use this object to write to stdout and stderr. 188 /// \param args The command line passed to the command broken by word, which 189 /// includes options and arguments. 190 /// 191 /// \return The exit code that the program has to return. 0 on success, some 192 /// other value on error. 193 /// \throw usage_error If args is invalid (i.e. if the options are mispecified 194 /// or if the arguments are invalid). 195 int 196 cmdline::base_command_no_data::main(cmdline::ui* ui, 197 const cmdline::args_vector& args) 198 { 199 return run(ui, parse_cmdline(args)); 200 } 201