alpar@2389
|
1 |
/* -*- C++ -*-
|
alpar@2389
|
2 |
*
|
alpar@2391
|
3 |
* This file is a part of LEMON, a generic C++ optimization library
|
alpar@2391
|
4 |
*
|
alpar@2391
|
5 |
* Copyright (C) 2003-2007
|
alpar@2391
|
6 |
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
alpar@2389
|
7 |
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
alpar@2389
|
8 |
*
|
alpar@2389
|
9 |
* Permission to use, modify and distribute this software is granted
|
alpar@2389
|
10 |
* provided that this copyright notice appears in all copies. For
|
alpar@2389
|
11 |
* precise terms see the accompanying LICENSE file.
|
alpar@2389
|
12 |
*
|
alpar@2389
|
13 |
* This software is provided "AS IS" with no warranty of any kind,
|
alpar@2389
|
14 |
* express or implied, and with no claim as to its suitability for any
|
alpar@2389
|
15 |
* purpose.
|
alpar@2389
|
16 |
*
|
alpar@2389
|
17 |
*/
|
alpar@2389
|
18 |
|
alpar@2389
|
19 |
#ifndef LEMON_ARG_PARSER
|
alpar@2389
|
20 |
#define LEMON_ARG_PARSER
|
alpar@2389
|
21 |
|
alpar@2389
|
22 |
#include <vector>
|
alpar@2389
|
23 |
#include <map>
|
alpar@2389
|
24 |
#include <list>
|
alpar@2389
|
25 |
#include <string>
|
alpar@2389
|
26 |
#include <iostream>
|
alpar@2389
|
27 |
#include <sstream>
|
alpar@2389
|
28 |
#include <algorithm>
|
alpar@2389
|
29 |
|
alpar@2389
|
30 |
///\ingroup misc
|
alpar@2389
|
31 |
///\file
|
alpar@2389
|
32 |
///\brief A tools to parse command line arguments.
|
alpar@2389
|
33 |
///
|
alpar@2389
|
34 |
///\author Alpar Juttner
|
alpar@2389
|
35 |
|
alpar@2389
|
36 |
namespace lemon {
|
alpar@2389
|
37 |
|
alpar@2389
|
38 |
///Command line arguments parser
|
alpar@2389
|
39 |
|
alpar@2389
|
40 |
///\ingroup misc
|
alpar@2389
|
41 |
///Command line arguments parser
|
alpar@2389
|
42 |
///
|
alpar@2389
|
43 |
class ArgParser {
|
alpar@2389
|
44 |
|
alpar@2389
|
45 |
static void _showHelp(void *p);
|
alpar@2389
|
46 |
protected:
|
alpar@2389
|
47 |
|
alpar@2389
|
48 |
int _argc;
|
alpar@2389
|
49 |
char **_argv;
|
alpar@2389
|
50 |
|
alpar@2389
|
51 |
enum OptType { UNKNOWN=0, BOOL=1, STRING=2, DOUBLE=3, INTEGER=4, FUNC=5 };
|
alpar@2389
|
52 |
|
alpar@2389
|
53 |
class ParData {
|
alpar@2389
|
54 |
public:
|
alpar@2389
|
55 |
union {
|
alpar@2389
|
56 |
bool *bool_p;
|
alpar@2389
|
57 |
int *int_p;
|
alpar@2389
|
58 |
double *double_p;
|
alpar@2389
|
59 |
std::string *string_p;
|
alpar@2389
|
60 |
struct {
|
alpar@2389
|
61 |
void (*p)(void *);
|
alpar@2389
|
62 |
void *data;
|
alpar@2389
|
63 |
} func_p;
|
alpar@2389
|
64 |
|
alpar@2389
|
65 |
};
|
alpar@2389
|
66 |
std::string help;
|
alpar@2389
|
67 |
bool mandatory;
|
alpar@2389
|
68 |
OptType type;
|
alpar@2389
|
69 |
bool set;
|
alpar@2389
|
70 |
bool ingroup;
|
alpar@2389
|
71 |
bool has_syn;
|
alpar@2389
|
72 |
bool syn;
|
alpar@2389
|
73 |
|
alpar@2389
|
74 |
ParData() : mandatory(false), type(UNKNOWN), set(false), ingroup(false),
|
alpar@2389
|
75 |
has_syn(false), syn(false) {}
|
alpar@2389
|
76 |
};
|
alpar@2389
|
77 |
|
alpar@2389
|
78 |
typedef std::map<std::string,ParData> Opts;
|
alpar@2389
|
79 |
Opts _opts;
|
alpar@2389
|
80 |
|
alpar@2389
|
81 |
class GroupData
|
alpar@2389
|
82 |
{
|
alpar@2389
|
83 |
public:
|
alpar@2389
|
84 |
typedef std::list<std::string> Opts;
|
alpar@2389
|
85 |
Opts opts;
|
alpar@2389
|
86 |
bool only_one;
|
alpar@2389
|
87 |
bool mandatory;
|
alpar@2389
|
88 |
GroupData() :only_one(false), mandatory(false) {}
|
alpar@2389
|
89 |
};
|
alpar@2389
|
90 |
|
alpar@2389
|
91 |
typedef std::map<std::string,GroupData> Groups;
|
alpar@2389
|
92 |
Groups _groups;
|
alpar@2389
|
93 |
|
alpar@2389
|
94 |
struct OtherArg
|
alpar@2389
|
95 |
{
|
alpar@2389
|
96 |
std::string name;
|
alpar@2389
|
97 |
std::string help;
|
alpar@2389
|
98 |
OtherArg(std::string n, std::string h) :name(n), help(h) {}
|
alpar@2389
|
99 |
|
alpar@2389
|
100 |
};
|
alpar@2389
|
101 |
|
alpar@2389
|
102 |
std::vector<OtherArg> _others_help;
|
alpar@2389
|
103 |
std::vector<std::string> _file_args;
|
alpar@2389
|
104 |
std::string _command_name;
|
alpar@2389
|
105 |
|
alpar@2389
|
106 |
public:
|
alpar@2389
|
107 |
|
alpar@2389
|
108 |
///\e
|
alpar@2389
|
109 |
ArgParser(int argc, char **argv);
|
alpar@2389
|
110 |
|
alpar@2389
|
111 |
///Add a new integer type option
|
alpar@2389
|
112 |
|
alpar@2389
|
113 |
///\param name The name of the option. The leading '-' must be omitted.
|
alpar@2389
|
114 |
///\param help A help string.
|
alpar@2389
|
115 |
///\retval value The value of the argument will be written to this variable.
|
alpar@2389
|
116 |
///\param obl Indicate if the option is mandatory.
|
alpar@2389
|
117 |
ArgParser &option(const std::string &name,
|
alpar@2389
|
118 |
const std::string &help,
|
alpar@2389
|
119 |
int &value, bool obl=false);
|
alpar@2389
|
120 |
|
alpar@2389
|
121 |
///Add a new floating type option
|
alpar@2389
|
122 |
|
alpar@2389
|
123 |
///\param name The name of the option. The leading '-' must be omitted.
|
alpar@2389
|
124 |
///\param help A help string.
|
alpar@2389
|
125 |
///\retval value The value of the argument will be written to this variable.
|
alpar@2389
|
126 |
///\param obl Indicate if the option is mandatory.
|
alpar@2389
|
127 |
ArgParser &option(const std::string &name,
|
alpar@2389
|
128 |
const std::string &help,
|
alpar@2389
|
129 |
double &value, bool obl=false);
|
alpar@2389
|
130 |
|
alpar@2389
|
131 |
///Add a new bool type option
|
alpar@2389
|
132 |
|
alpar@2389
|
133 |
///\param name The name of the option. The leading '-' must be omitted.
|
alpar@2389
|
134 |
///\param help A help string.
|
alpar@2389
|
135 |
///\retval value The value of the argument will be written to this variable.
|
alpar@2389
|
136 |
///\param obl Indicate if the option is mandatory.
|
alpar@2389
|
137 |
////\note A mandatory bool obtion is of very little use.)
|
alpar@2389
|
138 |
ArgParser &option(const std::string &name,
|
alpar@2389
|
139 |
const std::string &help,
|
alpar@2389
|
140 |
bool &value, bool obl=false);
|
alpar@2389
|
141 |
|
alpar@2389
|
142 |
///Add a new string type option
|
alpar@2389
|
143 |
|
alpar@2389
|
144 |
///\param name The name of the option. The leading '-' must be omitted.
|
alpar@2389
|
145 |
///\param help A help string.
|
alpar@2389
|
146 |
///\retval value The value of the argument will be written to this variable.
|
alpar@2389
|
147 |
///\param obl Indicate if the option is mandatory.
|
alpar@2389
|
148 |
ArgParser &option(const std::string &name,
|
alpar@2389
|
149 |
const std::string &help,
|
alpar@2389
|
150 |
std::string &value, bool obl=false);
|
alpar@2389
|
151 |
|
alpar@2389
|
152 |
///Bind a function to an option.
|
alpar@2389
|
153 |
|
alpar@2389
|
154 |
///\param name The name of the option. The leading '-' must be omitted.
|
alpar@2389
|
155 |
///\param help A help string.
|
alpar@2389
|
156 |
///\retval func The function to be called when the option is given. It
|
alpar@2389
|
157 |
/// must be of type "void f(void *)"
|
alpar@2389
|
158 |
///\param data Data to be passed to \c func
|
alpar@2389
|
159 |
ArgParser &option(const std::string &name,
|
alpar@2389
|
160 |
const std::string &help,
|
alpar@2389
|
161 |
void (*func)(void *),void *data);
|
alpar@2389
|
162 |
|
alpar@2389
|
163 |
///Boundle some options into a group
|
alpar@2389
|
164 |
|
alpar@2389
|
165 |
/// You can group some option by calling this function repeatedly for each
|
alpar@2389
|
166 |
/// option to be grupped with the same groupname.
|
alpar@2389
|
167 |
///\param group The group name
|
alpar@2389
|
168 |
///\param opt The option name
|
alpar@2389
|
169 |
ArgParser &optionGroup(const std::string &group,
|
alpar@2389
|
170 |
const std::string &opt);
|
alpar@2389
|
171 |
|
alpar@2389
|
172 |
///Make the members of a group exclusive
|
alpar@2389
|
173 |
|
alpar@2389
|
174 |
///If you call this function for a group, than at most one of them can be
|
alpar@2389
|
175 |
///given at the same time
|
alpar@2389
|
176 |
ArgParser &onlyOneGroup(const std::string &group);
|
alpar@2389
|
177 |
|
alpar@2389
|
178 |
///Create synonym to an option
|
alpar@2389
|
179 |
|
alpar@2389
|
180 |
///With this function you can create a sysnonym called \c sys of the
|
alpar@2389
|
181 |
///option \c opt.
|
alpar@2389
|
182 |
ArgParser &synonym(const std::string &syn,
|
alpar@2389
|
183 |
const std::string &opt);
|
alpar@2389
|
184 |
|
alpar@2389
|
185 |
///Make a group mandatory
|
alpar@2389
|
186 |
|
alpar@2389
|
187 |
///Using this function, at least one of the members of \c group
|
alpar@2389
|
188 |
///must be given.
|
alpar@2389
|
189 |
ArgParser &mandatoryGroup(const std::string &group);
|
alpar@2389
|
190 |
|
alpar@2389
|
191 |
///Give help string for non-parsed arguments.
|
alpar@2389
|
192 |
|
alpar@2389
|
193 |
///With this function you can give help string for non-parsed arguments.
|
alpar@2389
|
194 |
///the parameter \c name will be printed in the short usage line, while
|
alpar@2389
|
195 |
///\c help gives a more detailed description.
|
alpar@2389
|
196 |
ArgParser &other(const std::string &name,
|
alpar@2389
|
197 |
const std::string &help="");
|
alpar@2389
|
198 |
|
alpar@2389
|
199 |
///Non option type arguments.
|
alpar@2389
|
200 |
|
alpar@2389
|
201 |
///Gives back a reference to a vector consisting of the program arguments
|
alpar@2389
|
202 |
///not starting with a '-' character.
|
alpar@2389
|
203 |
std::vector<std::string> &files() { return _file_args; }
|
alpar@2389
|
204 |
|
alpar@2389
|
205 |
///Give back the command name (the 0th argument)
|
alpar@2389
|
206 |
const std::string &commandName() { return _command_name; }
|
alpar@2389
|
207 |
|
alpar@2389
|
208 |
void show(std::ostream &os,Opts::iterator i);
|
alpar@2389
|
209 |
void show(std::ostream &os,Groups::iterator i);
|
alpar@2389
|
210 |
void showHelp(Opts::iterator i);
|
alpar@2389
|
211 |
void showHelp(std::vector<OtherArg>::iterator i);
|
alpar@2389
|
212 |
void shortHelp();
|
alpar@2389
|
213 |
void showHelp();
|
alpar@2389
|
214 |
|
alpar@2389
|
215 |
void unknownOpt(std::string arg);
|
alpar@2389
|
216 |
|
alpar@2389
|
217 |
void requiresValue(std::string arg, OptType t);
|
alpar@2389
|
218 |
void checkMandatories();
|
alpar@2389
|
219 |
|
alpar@2389
|
220 |
///\e
|
alpar@2389
|
221 |
ArgParser &parse();
|
alpar@2389
|
222 |
|
alpar@2389
|
223 |
/// Synonym for parse()
|
alpar@2389
|
224 |
ArgParser &run()
|
alpar@2389
|
225 |
{
|
alpar@2389
|
226 |
return parse();
|
alpar@2389
|
227 |
}
|
alpar@2389
|
228 |
|
alpar@2389
|
229 |
///Check if an opion has been given to the command.
|
alpar@2389
|
230 |
bool given(std::string op)
|
alpar@2389
|
231 |
{
|
alpar@2389
|
232 |
Opts::iterator i = _opts.find(op);
|
alpar@2389
|
233 |
return i!=_opts.end()?i->second.set:false;
|
alpar@2389
|
234 |
}
|
alpar@2389
|
235 |
|
alpar@2389
|
236 |
};
|
alpar@2389
|
237 |
}
|
alpar@2389
|
238 |
|
alpar@2389
|
239 |
|
alpar@2389
|
240 |
|
alpar@2389
|
241 |
#endif // LEMON_MAIN_PARAMS
|