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