aboutsummaryrefslogtreecommitdiffstats
path: root/tests/lib/unit++/optmap.h
blob: 521227979f637e613f89fc2b7ad2c3c87a014cb1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
// Copyright (C) 2001 Claus Dr�by
// Terms of use are in the file COPYING
#ifndef __UNITPP__OPTMAP_H
#define __UNITPP__OPTMAP_H
#include <string>
#include <map>
#include <vector>
#include <stdexcept>
/**
 * The home of \Ref{optmap}. This is a unified way of handling commang line
 * arguments, and suitable usage replies when things goes badly.
 */
namespace options_utils {
/**
 * A argument option handler, based on the Command pattern. Each option is
 * associated with a handling command object.
 *
 * The map keeps the reverse association as well, to allow printing of a
 * using line.
 */
class optmap {
public:
	/**
	 * The base for all option handlers.
	 *
	 * To handle a new kind of commands, just derive a class from this an
	 * overload the methods to do the work.
	 */
	struct cmd {
		/**
		 * Performing the work associated with the option.
		 *
		 * To obtain an argument see \Ref{get_arg}
		 * @return true if the parsing was succesfull
		 */
		virtual bool do_cmd(optmap* om) = 0;
		/// return the name of the argument needed by \Ref{usage}
		virtual std::string arg() { return std::string(); }
		virtual ~cmd() {}
	};
	/**
	 * The very simple constructor for an optmap object. Please note that
	 * copying of optmaps are not supported.
	 * @param usage The tail of the usage string to follow the options
	 */
	optmap(const char* usage = "");
	~optmap();
	/**
	 * Adds an option that invokes the command handler.
	 *
	 * This is the low level work horse for all the add methods. All the
	 * other adds works by adding appropriate cmd objects for doing the work.
	 *
	 * @param o
	 *	The option name. If the length of the option is 1 it will be an old
	 *	fashion option, otherwise it will be a GNU stype long option
	 *	(--long-opt).
	 * @param h
	 *	The pointer to the handler. The optmap assumes ownership of the
	 *	pointer and delete it in the destructor.
	 *
	 * @return *this
	 */
	optmap& add(const char* o, cmd* h);
	/// Adds an alias for an option.
	optmap& alias(const char* new_opt, const char* old_opt);
	/**
	 * Parse the command line.
	 * @return true if the parse is valid, false otherwise.
	 */
	bool parse(int argc, const char** argv);
	/// Gets the index for the first non option argument
	int n() { return i; }
	/// display a usage string and abort()
	void usage(bool abort = true);
	/// get the argument of an option; mainly for cmd implementations.
	const char* get_arg();
private:
	int i;
	const char* prog;
	int argc;
	const char** argv;
	bool multichar;	// doing a multichar, -pdf --> -p -d -f
	bool first_multi;
	optmap(const optmap& o);
	optmap& operator=(const optmap&);
	bool do_cmd(const std::string& opt);
	std::string tail;
	typedef std::map<std::string, cmd*> cmds_t;
	cmds_t cmds;
	typedef std::vector<cmd*> gvec_t;
	gvec_t gvec;
	typedef std::map<cmd*, std::vector<std::string> > group_t;
	group_t group;
};

/// A cmd handler that can set a boolean flag.
class opt_flag : public optmap::cmd {
	bool& flg;
public:
	/// Just give it the bool you want set if the flag is present.
	opt_flag(bool& flg) : flg(flg) {}
	virtual bool do_cmd(optmap*) { flg = true; return true; }
};

/// A cmd handler that can get an integer value.
class opt_int : public optmap::cmd {
	int& val;
public:
	/// just give it an int variable that the flag argument can be assigned to.
	opt_int(int& val) : val(val) {}
	virtual bool do_cmd(optmap* om);
	virtual std::string arg() { return std::string("<int>"); }
};
/// A cmd handler for a string
class opt_string : public optmap::cmd {
	std::string& val;
public:
	/// Give it a string that the flag arg should be assigned to.
	opt_string(std::string& val) : val(val) {}
	virtual bool do_cmd(optmap* om);
	virtual std::string arg() { return std::string("<string>"); }
};
}
#endif