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 |
//$Id$ |
966 |
11 Oct 07 |
peter |
5 |
|
966 |
11 Oct 07 |
peter |
6 |
/* |
4359 |
23 Aug 23 |
peter |
Copyright (C) 2007 Peter Johansson |
4359 |
23 Aug 23 |
peter |
Copyright (C) 2008, 2009 Jari Häkkinen, Peter Johansson |
4359 |
23 Aug 23 |
peter |
Copyright (C) 2010, 2011, 2013, 2014 Peter Johansson |
966 |
11 Oct 07 |
peter |
10 |
|
1437 |
25 Aug 08 |
peter |
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 |
The yat library is free software; you can redistribute it and/or |
966 |
11 Oct 07 |
peter |
modify it under the terms of the GNU General Public License as |
1486 |
09 Sep 08 |
jari |
published by the Free Software Foundation; either version 3 of the |
966 |
11 Oct 07 |
peter |
License, or (at your option) any later version. |
966 |
11 Oct 07 |
peter |
17 |
|
966 |
11 Oct 07 |
peter |
The yat library is distributed in the hope that it will be useful, |
966 |
11 Oct 07 |
peter |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
966 |
11 Oct 07 |
peter |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
966 |
11 Oct 07 |
peter |
General Public License for more details. |
966 |
11 Oct 07 |
peter |
22 |
|
966 |
11 Oct 07 |
peter |
You should have received a copy of the GNU General Public License |
1487 |
10 Sep 08 |
jari |
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 |
@brief Class for parsing the command line. |
4200 |
19 Aug 22 |
peter |
46 |
|
966 |
11 Oct 07 |
peter |
Provides parsing and storage of command line arguments. The class |
966 |
11 Oct 07 |
peter |
is typically used by hooking a number of Option objects to |
966 |
11 Oct 07 |
peter |
CommandLine, and then call the parse() function. Here is a short |
966 |
11 Oct 07 |
peter |
example how the class may be used: |
4200 |
19 Aug 22 |
peter |
51 |
|
966 |
11 Oct 07 |
peter |
\code |
4200 |
19 Aug 22 |
peter |
53 |
|
966 |
11 Oct 07 |
peter |
CommandLine cmd; |
982 |
22 Oct 07 |
peter |
OptionHelp help(cmd); |
4200 |
19 Aug 22 |
peter |
OptionFile in(cmd, "i,in", |
2054 |
06 Sep 09 |
peter |
"Read input from file (rather than standard input)", |
2054 |
06 Sep 09 |
peter |
false, true, "r"); |
2054 |
06 Sep 09 |
peter |
OptionFile out(cmd, "o,out", "Place the output to file", false, false, "w"); |
966 |
11 Oct 07 |
peter |
OptionSwitch target(cmd, "T,target", "treat DEST as a normal file", true); |
966 |
11 Oct 07 |
peter |
OptionSwitch verbose(cmd, "v,verbose", "explain what is being done"); |
966 |
11 Oct 07 |
peter |
OptionSwitch version(cmd, "version", "output version and exit"); |
1954 |
07 May 09 |
jari |
std::stringstream copyright; |
1954 |
07 May 09 |
jari |
copyright << "example 1.0\n" |
1954 |
07 May 09 |
jari |
<< "Copyright (C) 2007 Peter Johansson\n\n" |
1954 |
07 May 09 |
jari |
<< "This is free software see the source for copying " |
1954 |
07 May 09 |
jari |
<< "conditions. There is NO\nwarranty; not even for " |
1954 |
07 May 09 |
jari |
<< "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"; |
966 |
11 Oct 07 |
peter |
try { |
966 |
11 Oct 07 |
peter |
cmd.parse(argc, argv); |
966 |
11 Oct 07 |
peter |
71 |
} |
1197 |
03 Mar 08 |
peter |
catch (cmd_error& e){ |
1437 |
25 Aug 08 |
peter |
if (version.present()){ |
4200 |
19 Aug 22 |
peter |
std::cout << copyright.str(); |
1954 |
07 May 09 |
jari |
return EXIT_SUCCESS; |
1437 |
25 Aug 08 |
peter |
76 |
} |
1954 |
07 May 09 |
jari |
std::cerr << e.what() << std::endl; |
1954 |
07 May 09 |
jari |
return EXIT_FAILURE; |
4200 |
19 Aug 22 |
peter |
79 |
} |
1954 |
07 May 09 |
jari |
if (version.present()){ |
4200 |
19 Aug 22 |
peter |
std::cout << copyright.str(); |
1954 |
07 May 09 |
jari |
return EXIT_SUCCESS; |
1954 |
07 May 09 |
jari |
83 |
} |
2054 |
06 Sep 09 |
peter |
StreamRedirect sr_out(std::cout, out.value(), out.present()); |
2054 |
06 Sep 09 |
peter |
StreamRedirect sr_in(std::cin, in.value(), in.present()); |
966 |
11 Oct 07 |
peter |
86 |
... |
966 |
11 Oct 07 |
peter |
\endcode |
966 |
11 Oct 07 |
peter |
88 |
|
966 |
11 Oct 07 |
peter |
After creation a number of Option classes are hooked up to the |
4200 |
19 Aug 22 |
peter |
CommandLine object in their constructors. |
966 |
11 Oct 07 |
peter |
91 |
|
966 |
11 Oct 07 |
peter |
Each parameter is associated to a one-character flag and/or a |
966 |
11 Oct 07 |
peter |
longer string flag. The longer flag expects to be preceded by |
966 |
11 Oct 07 |
peter |
'--' as e.g. '--help' for help. The shorter flag expects to be |
966 |
11 Oct 07 |
peter |
preceded by '-' as e.g. '-h', and can also be concatenated like |
966 |
11 Oct 07 |
peter |
"program -vf", which is equivalent to "program -v -f". or |
1197 |
03 Mar 08 |
peter |
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 |
\brief default constructor |
982 |
22 Oct 07 |
peter |
104 |
|
982 |
22 Oct 07 |
peter |
\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 |
\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 |
\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 |
\brief Allow at most \a n free arguments. |
1468 |
02 Sep 08 |
peter |
121 |
|
2808 |
05 Aug 12 |
peter |
A free argument is an argument not associated with an Option, |
1468 |
02 Sep 08 |
peter |
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 |
\brief Arguments not associated with an Option |
1480 |
09 Sep 08 |
peter |
129 |
|
1480 |
09 Sep 08 |
peter |
\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 |
\brief parse the commandline |
966 |
11 Oct 07 |
peter |
136 |
|
2046 |
02 Sep 09 |
peter |
First the commandline is parsed to detect which options are |
2046 |
02 Sep 09 |
peter |
present, then each Option parses the its relevant part of |
2046 |
02 Sep 09 |
peter |
commandline (Option::parse()), and finally each Option is |
2046 |
02 Sep 09 |
peter |
validated (Option::validate()). |
2046 |
02 Sep 09 |
peter |
141 |
|
1178 |
27 Feb 08 |
peter |
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 |
\brief has the commandline been parsed already |
1741 |
22 Jan 09 |
peter |
148 |
|
1741 |
22 Jan 09 |
peter |
\return true if parse function has already been called |
1741 |
22 Jan 09 |
peter |
150 |
|
1741 |
22 Jan 09 |
peter |
\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 |
@return Name of more; more specifically argv[0] is |
966 |
11 Oct 07 |
peter |
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 |
\brief Sort Options how they will appear in (help) output. |
2265 |
05 Jun 10 |
peter |
163 |
|
2265 |
05 Jun 10 |
peter |
This function will sort the Options in alphabetical order. If |
2265 |
05 Jun 10 |
peter |
the Option has a long_name, it is used for the sorting; |
2265 |
05 Jun 10 |
peter |
otherwise, the short_name is used. |
2265 |
05 Jun 10 |
peter |
167 |
|
2265 |
05 Jun 10 |
peter |
\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 |
Like sort(void) but using \a compare to sort Options. |
2265 |
05 Jun 10 |
peter |
174 |
|
2265 |
05 Jun 10 |
peter |
The functor Compare must be a <a |
2287 |
28 Jun 10 |
peter |
href="http://www.sgi.com/tech/stl/BinaryPredicate.html">Binary |
2287 |
28 Jun 10 |
peter |
Predicate</a> with both argument types \c const \c Option*. |
2265 |
05 Jun 10 |
peter |
178 |
|
2265 |
05 Jun 10 |
peter |
\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 |
\return something like "Try '<program_name()> --help' for |
966 |
11 Oct 07 |
peter |
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 |
// use cond to make doxygen ignore this privat class |
3188 |
25 Mar 14 |
peter |
/// \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 |
/// \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 |
\brief CommandLine output operator |
1437 |
25 Aug 08 |
peter |
223 |
|
1437 |
25 Aug 08 |
peter |
A typical output may look like this |
1437 |
25 Aug 08 |
peter |
\verbatim |
1437 |
25 Aug 08 |
peter |
Available options are: |
1437 |
25 Aug 08 |
peter |
-h, --help display this help and exit |
1437 |
25 Aug 08 |
peter |
-v, --verbose explain what is being done |
1437 |
25 Aug 08 |
peter |
\endverbatim |
1437 |
25 Aug 08 |
peter |
The output starts with a descriptive line such as "Available |
1437 |
25 Aug 08 |
peter |
options are:" (default) that can be set in constructor. Then follows the |
1437 |
25 Aug 08 |
peter |
options described in the order they were added to |
1437 |
25 Aug 08 |
peter |
Commandline. Each Option is described according to |
1437 |
25 Aug 08 |
peter |
Option::print(void) function. |
1437 |
25 Aug 08 |
peter |
\see OptionHelp |
1887 |
31 Mar 09 |
peter |
236 |
|
1887 |
31 Mar 09 |
peter |
\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 |