source: trunk/yat/utility/CommandLine.h

Last change on this file was 4359, checked in by Peter, 4 weeks ago

update copyright years using svndigest 0.11 (in contrast to 0.10.x previously)

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