yat/utility/CommandLine.h

Code
Comments
Other
Rev Date Author Line
966 11 Oct 07 peter 1 #ifndef _theplu_yat_utility_commandline_
966 11 Oct 07 peter 2 #define _theplu_yat_utility_commandline_
966 11 Oct 07 peter 3
966 11 Oct 07 peter 4 //$Id$
966 11 Oct 07 peter 5
966 11 Oct 07 peter 6 /*
4359 23 Aug 23 peter 7   Copyright (C) 2007 Peter Johansson
4359 23 Aug 23 peter 8   Copyright (C) 2008, 2009 Jari H√§kkinen, Peter Johansson
4359 23 Aug 23 peter 9   Copyright (C) 2010, 2011, 2013, 2014 Peter Johansson
966 11 Oct 07 peter 10
1437 25 Aug 08 peter 11   This file is part of the yat library, http://dev.thep.lu.se/yat
966 11 Oct 07 peter 12
966 11 Oct 07 peter 13   The yat library is free software; you can redistribute it and/or
966 11 Oct 07 peter 14   modify it under the terms of the GNU General Public License as
1486 09 Sep 08 jari 15   published by the Free Software Foundation; either version 3 of the
966 11 Oct 07 peter 16   License, or (at your option) any later version.
966 11 Oct 07 peter 17
966 11 Oct 07 peter 18   The yat library is distributed in the hope that it will be useful,
966 11 Oct 07 peter 19   but WITHOUT ANY WARRANTY; without even the implied warranty of
966 11 Oct 07 peter 20   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
966 11 Oct 07 peter 21   General Public License for more details.
966 11 Oct 07 peter 22
966 11 Oct 07 peter 23   You should have received a copy of the GNU General Public License
1487 10 Sep 08 jari 24   along with yat. If not, see <http://www.gnu.org/licenses/>.
966 11 Oct 07 peter 25 */
966 11 Oct 07 peter 26
2265 05 Jun 10 peter 27 #include <algorithm>
966 11 Oct 07 peter 28 #include <cctype>
966 11 Oct 07 peter 29 #include <map>
2046 02 Sep 09 peter 30 #include <iosfwd>
966 11 Oct 07 peter 31 #include <sstream>
966 11 Oct 07 peter 32 #include <stdexcept>
966 11 Oct 07 peter 33 #include <string>
966 11 Oct 07 peter 34 #include <typeinfo>
966 11 Oct 07 peter 35 #include <utility>
966 11 Oct 07 peter 36 #include <vector>
966 11 Oct 07 peter 37
966 11 Oct 07 peter 38 namespace theplu {
966 11 Oct 07 peter 39 namespace yat {
966 11 Oct 07 peter 40 namespace utility {
966 11 Oct 07 peter 41
966 11 Oct 07 peter 42   class Option;
966 11 Oct 07 peter 43
966 11 Oct 07 peter 44   /**
966 11 Oct 07 peter 45      @brief Class for parsing the command line.
4200 19 Aug 22 peter 46
966 11 Oct 07 peter 47      Provides parsing and storage of command line arguments. The class
966 11 Oct 07 peter 48      is typically used by hooking a number of Option objects to
966 11 Oct 07 peter 49      CommandLine, and then call the parse() function. Here is a short
966 11 Oct 07 peter 50      example how the class may be used:
4200 19 Aug 22 peter 51
966 11 Oct 07 peter 52      \code
4200 19 Aug 22 peter 53
966 11 Oct 07 peter 54      CommandLine cmd;
982 22 Oct 07 peter 55      OptionHelp help(cmd);
4200 19 Aug 22 peter 56      OptionFile in(cmd, "i,in",
2054 06 Sep 09 peter 57                    "Read input from file (rather than standard input)",
2054 06 Sep 09 peter 58                    false, true, "r");
2054 06 Sep 09 peter 59      OptionFile out(cmd, "o,out", "Place the output to file", false, false, "w");
966 11 Oct 07 peter 60      OptionSwitch target(cmd, "T,target", "treat DEST as a normal file", true);
966 11 Oct 07 peter 61      OptionSwitch verbose(cmd, "v,verbose", "explain what is being done");
966 11 Oct 07 peter 62      OptionSwitch version(cmd, "version", "output version and exit");
1954 07 May 09 jari 63      std::stringstream copyright;
1954 07 May 09 jari 64      copyright << "example 1.0\n"
1954 07 May 09 jari 65                << "Copyright (C) 2007 Peter Johansson\n\n"
1954 07 May 09 jari 66                << "This is free software see the source for copying "
1954 07 May 09 jari 67                << "conditions. There is NO\nwarranty; not even for "
1954 07 May 09 jari 68                << "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n";
966 11 Oct 07 peter 69      try {
966 11 Oct 07 peter 70        cmd.parse(argc, argv);
966 11 Oct 07 peter 71      }
1197 03 Mar 08 peter 72      catch (cmd_error& e){
1437 25 Aug 08 peter 73        if (version.present()){
4200 19 Aug 22 peter 74          std::cout << copyright.str();
1954 07 May 09 jari 75          return EXIT_SUCCESS;
1437 25 Aug 08 peter 76        }
1954 07 May 09 jari 77        std::cerr << e.what() << std::endl;
1954 07 May 09 jari 78        return EXIT_FAILURE;
4200 19 Aug 22 peter 79      }
1954 07 May 09 jari 80      if (version.present()){
4200 19 Aug 22 peter 81        std::cout << copyright.str();
1954 07 May 09 jari 82        return EXIT_SUCCESS;
1954 07 May 09 jari 83      }
2054 06 Sep 09 peter 84      StreamRedirect sr_out(std::cout, out.value(), out.present());
2054 06 Sep 09 peter 85      StreamRedirect sr_in(std::cin, in.value(), in.present());
966 11 Oct 07 peter 86      ...
966 11 Oct 07 peter 87      \endcode
966 11 Oct 07 peter 88
966 11 Oct 07 peter 89      After creation a number of Option classes are hooked up to the
4200 19 Aug 22 peter 90      CommandLine object in their constructors.
966 11 Oct 07 peter 91
966 11 Oct 07 peter 92      Each parameter is associated to a one-character flag and/or a
966 11 Oct 07 peter 93      longer string flag. The longer flag expects to be preceded by
966 11 Oct 07 peter 94      '--' as e.g. '--help' for help. The shorter flag expects to be
966 11 Oct 07 peter 95      preceded by '-' as e.g. '-h', and can also be concatenated like
966 11 Oct 07 peter 96      "program -vf", which is equivalent to "program -v -f". or
1197 03 Mar 08 peter 97      its sibblings for different types.
966 11 Oct 07 peter 98   */
966 11 Oct 07 peter 99   class CommandLine
966 11 Oct 07 peter 100   {
966 11 Oct 07 peter 101   public:
966 11 Oct 07 peter 102     /**
1253 03 Apr 08 peter 103        \brief default constructor
982 22 Oct 07 peter 104
982 22 Oct 07 peter 105        \param str text preceeding the list of option in output
966 11 Oct 07 peter 106     */
982 22 Oct 07 peter 107     CommandLine(std::string str="Available options are:");
966 11 Oct 07 peter 108
966 11 Oct 07 peter 109     /**
966 11 Oct 07 peter 110        \brief Destructor
966 11 Oct 07 peter 111     */
966 11 Oct 07 peter 112     virtual ~CommandLine(void);
966 11 Oct 07 peter 113
966 11 Oct 07 peter 114     /**
4200 19 Aug 22 peter 115        \brief Function to add an option.
966 11 Oct 07 peter 116     */
966 11 Oct 07 peter 117     void add(Option&);
966 11 Oct 07 peter 118
966 11 Oct 07 peter 119     /**
1468 02 Sep 08 peter 120        \brief Allow at most \a n free arguments.
1468 02 Sep 08 peter 121
2808 05 Aug 12 peter 122        A free argument is an argument not associated with an Option,
1468 02 Sep 08 peter 123        allowing commandlines such as \code prog foo bar \endcode
1468 02 Sep 08 peter 124      */
1468 02 Sep 08 peter 125     void allow_free_args(size_t n);
1468 02 Sep 08 peter 126
1468 02 Sep 08 peter 127     /**
1480 09 Sep 08 peter 128        \brief Arguments not associated with an Option
1480 09 Sep 08 peter 129
1480 09 Sep 08 peter 130        \see allow_free_args(size_t n)
1480 09 Sep 08 peter 131     */
1480 09 Sep 08 peter 132     const std::vector<std::string>& free_args(void) const;
1480 09 Sep 08 peter 133
1480 09 Sep 08 peter 134     /**
966 11 Oct 07 peter 135        \brief parse the commandline
966 11 Oct 07 peter 136
2046 02 Sep 09 peter 137        First the commandline is parsed to detect which options are
2046 02 Sep 09 peter 138        present, then each Option parses the its relevant part of
2046 02 Sep 09 peter 139        commandline (Option::parse()), and finally each Option is
2046 02 Sep 09 peter 140        validated (Option::validate()).
2046 02 Sep 09 peter 141
1178 27 Feb 08 peter 142        throw cmd_error if an error is detected.
966 11 Oct 07 peter 143     */
966 11 Oct 07 peter 144     void parse(int argc, char* argv[]);
966 11 Oct 07 peter 145
966 11 Oct 07 peter 146     /**
1741 22 Jan 09 peter 147        \brief has the commandline been parsed already
1741 22 Jan 09 peter 148
1741 22 Jan 09 peter 149        \return true if parse function has already been called
1741 22 Jan 09 peter 150
1741 22 Jan 09 peter 151        \since New in yat 0.5
1741 22 Jan 09 peter 152     */
1741 22 Jan 09 peter 153     bool parsed(void) const;
1741 22 Jan 09 peter 154
1741 22 Jan 09 peter 155     /**
966 11 Oct 07 peter 156        @return Name of more; more specifically argv[0] is
966 11 Oct 07 peter 157        stripped so only string after the last '/' remains.
966 11 Oct 07 peter 158       */
966 11 Oct 07 peter 159     std::string program_name(void) const;
966 11 Oct 07 peter 160
966 11 Oct 07 peter 161     /**
2265 05 Jun 10 peter 162        \brief Sort Options how they will appear in (help) output.
2265 05 Jun 10 peter 163
2265 05 Jun 10 peter 164        This function will sort the Options in alphabetical order. If
2265 05 Jun 10 peter 165        the Option has a long_name, it is used for the sorting;
2265 05 Jun 10 peter 166        otherwise, the short_name is used.
2265 05 Jun 10 peter 167
2265 05 Jun 10 peter 168        \since New in yat 0.7
2265 05 Jun 10 peter 169      */
2265 05 Jun 10 peter 170     void sort(void);
2265 05 Jun 10 peter 171
2265 05 Jun 10 peter 172     /**
2265 05 Jun 10 peter 173        Like sort(void) but using \a compare to sort Options.
2265 05 Jun 10 peter 174
2265 05 Jun 10 peter 175        The functor Compare must be a <a
2287 28 Jun 10 peter 176        href="http://www.sgi.com/tech/stl/BinaryPredicate.html">Binary
2287 28 Jun 10 peter 177        Predicate</a> with both argument types \c const \c Option*.
2265 05 Jun 10 peter 178
2265 05 Jun 10 peter 179        \since New in yat 0.7
2265 05 Jun 10 peter 180      */
2265 05 Jun 10 peter 181     template<class Compare>
2265 05 Jun 10 peter 182     void sort(Compare compare);
2265 05 Jun 10 peter 183
2265 05 Jun 10 peter 184     /**
2964 22 Jan 13 peter 185        \return something like "Try '<program_name()> --help' for
966 11 Oct 07 peter 186        more information."
966 11 Oct 07 peter 187      */
966 11 Oct 07 peter 188     std::string try_help(void) const;
966 11 Oct 07 peter 189
966 11 Oct 07 peter 190   private:
981 22 Oct 07 peter 191     friend std::ostream& operator<<(std::ostream& os, const CommandLine& cl);
966 11 Oct 07 peter 192     bool is_long_option(std::string str) const;
966 11 Oct 07 peter 193     bool is_short_option(std::string str) const;
2458 03 Apr 11 peter 194     void parse(std::vector<std::string>::iterator& first,
2458 03 Apr 11 peter 195                std::vector<std::string>::iterator& last);
2458 03 Apr 11 peter 196     void parse_long(std::vector<std::string>::iterator& first,
2458 03 Apr 11 peter 197                     std::vector<std::string>::iterator& last);
2458 03 Apr 11 peter 198     void parse_short(std::vector<std::string>::iterator& first,
2458 03 Apr 11 peter 199                      std::vector<std::string>::iterator& last);
2458 03 Apr 11 peter 200     void parse_free_arg(std::vector<std::string>::iterator& first,
2458 03 Apr 11 peter 201                         std::vector<std::string>::iterator& last);
982 22 Oct 07 peter 202     std::string description_;
1466 02 Sep 08 peter 203     std::vector<std::string> free_arg_;
1468 02 Sep 08 peter 204     size_t free_arg_max_;
966 11 Oct 07 peter 205     std::vector<Option*> options_;
966 11 Oct 07 peter 206     std::map<char, Option*> short_options_;
966 11 Oct 07 peter 207     std::map<std::string, Option*> long_options_;
1741 22 Jan 09 peter 208     bool parsed_;
966 11 Oct 07 peter 209     std::string program_name_;
2265 05 Jun 10 peter 210
2288 28 Jun 10 peter 211     // use cond to make doxygen ignore this privat class
3188 25 Mar 14 peter 212     /// \cond IGNORE_DOXYGEN
2265 05 Jun 10 peter 213     struct OptionCompare
2265 05 Jun 10 peter 214     {
2265 05 Jun 10 peter 215       bool operator()(const Option*, const Option*) const;
2265 05 Jun 10 peter 216     };
2287 28 Jun 10 peter 217     /// \endcond
2265 05 Jun 10 peter 218
966 11 Oct 07 peter 219   };
966 11 Oct 07 peter 220
966 11 Oct 07 peter 221   /**
966 11 Oct 07 peter 222      \brief CommandLine output operator
1437 25 Aug 08 peter 223
1437 25 Aug 08 peter 224      A typical output may look like this
1437 25 Aug 08 peter 225      \verbatim
1437 25 Aug 08 peter 226      Available options are:
1437 25 Aug 08 peter 227      -h, --help      display this help and exit
1437 25 Aug 08 peter 228      -v, --verbose   explain what is being done
1437 25 Aug 08 peter 229      \endverbatim
1437 25 Aug 08 peter 230      The output starts with a descriptive line such as "Available
1437 25 Aug 08 peter 231      options are:" (default) that can be set in constructor. Then follows the
1437 25 Aug 08 peter 232      options described in the order they were added to
1437 25 Aug 08 peter 233      Commandline. Each Option is described according to
1437 25 Aug 08 peter 234      Option::print(void) function.
1437 25 Aug 08 peter 235      \see OptionHelp
1887 31 Mar 09 peter 236
1887 31 Mar 09 peter 237      \relates CommandLine
966 11 Oct 07 peter 238   */
981 22 Oct 07 peter 239   std::ostream& operator<<(std::ostream&, const CommandLine&);
966 11 Oct 07 peter 240
2265 05 Jun 10 peter 241   template<class Compare>
2265 05 Jun 10 peter 242   void CommandLine::sort(Compare compare)
2265 05 Jun 10 peter 243   {
2265 05 Jun 10 peter 244     std::sort(options_.begin(), options_.end(), compare);
2265 05 Jun 10 peter 245   }
2265 05 Jun 10 peter 246
966 11 Oct 07 peter 247 }}} // end of namespace utility, yat, and theplu
966 11 Oct 07 peter 248
966 11 Oct 07 peter 249 #endif