1 // -*- c++ -*-
2 //------------------------------------------------------------------------------
3 // $Id: CmdLineOpts.h,v 1.7 2005/10/12 02:28:58 vlg Exp $
4 //------------------------------------------------------------------------------
5 //                             CmdLineOpts.h
6 //------------------------------------------------------------------------------
7 //  Copyright (C) 2000,2005  Vladislav Grinchenko
8 //
9 //  This library is free software; you can redistribute it and/or
10 //  modify it under the terms of the GNU Library General Public
11 //  License as published by the Free Software Foundation; either
12 //  version 2 of the License, or (at your option) any later version.
13 //------------------------------------------------------------------------------
14 
15 #ifndef CMD_LINE_OPTS_H
16 #define CMD_LINE_OPTS_H
17 
18 #include "assa/Assure.h"
19 
20 #include <string>
21 #include <vector>
22 using std::string;
23 using std::vector;
24 
25 namespace ASSA {
26 
27 class CmdLineOpts;
28 
29 /** @file CmdLineOpts.h
30 
31  	Class to handle processing command-line options.
32  */
33 
34 /**
35  * Option class. This class is a helper class of CmdLineOpts class.
36  * It is not used by any other class and cannot be instantiated.
37  */
38 
39 class Option {
40 public:
41 	friend class CmdLineOpts;
42 
43 	/** @enum type_t
44 		Option type. Each option, except for flags has a value
45 		following it on the command line. Following types are supported:
46 	*/
47 	enum type_t {
48 		string_t=0,	/**< Convert argument to STL string  */
49 		int_t,		/**< Convert argument to int  */
50 		uint_t,		/**< Convert argument to unsigned int  */
51 		long_t,		/**< Convert argument to long  */
52 		ulong_t,	/**< Convert argument to unsinged long  */
53 		double_t,	/**< Convert argument to double  */
54 		float_t,	/**< Convert argument to float  */
55 		flag_t,		/**< No argument; bool value is flipped.  */
56 		func_t,		/**< Convert argument to function  */
57 		func_one_t,	/**< Convert argument to function with one argument  */
58 		none_t
59 	};
60 
61 private:
62 	/// Private default constructor
63 	Option ();
64 
65 	/// Private constructor
66 	Option (char shopt_, const string& lopt_, type_t type_, void* val_);
67 
68 	/// Write object state to the log file
69 	void dump () const;
70 
71 	/// Return the type of the Option object
72 	const char* type_c_str ();
73 
74 private:
75 	/// One-letter option name
76 	char    m_short_name;
77 
78 	/// Long option name
79 	string  m_long_name;
80 
81 	/// Option type
82 	type_t  m_type;
83 
84 	/// Pointer to the option value
85 	void*   m_val;
86 };
87 
88 inline
Option()89 Option::Option () :
90 	m_short_name (' '), m_long_name (""), m_type (none_t), m_val (NULL)
91 {
92 	/* empty */
93 }
94 
95 inline
Option(char shopt_,const string & lopt_,type_t type_,void * val_)96 Option::Option (char shopt_, const string& lopt_, type_t type_, void* val_) :
97 	m_short_name (shopt_), 	m_long_name (lopt_),
98 	m_type (type_), m_val (val_)
99 {
100 	trace_with_mask("Option::Option", CMDLINEOPTS);
101 }
102 
103 /*----------------------------------------------------------------------------*/
104 class IniFile;
105 
106 /** Class CmdLineOpts.
107 
108 CmdLineOpts class parsers the command line arguments. It is a base class,
109 and to use it, it has to be inherited from. See "ASSA Library User's
110 Guide" for further details.
111 */
112 
113 class CmdLineOpts
114 {
115 public:
116 	typedef void (* OPTS_FUNC) (void);
117 	typedef void (* OPTS_FUNC_ONE) (const string&);
118 
119 	typedef vector<Option> OptionSet;
120 
121 	/// Default constructor
122 	CmdLineOpts ();
123 
124 	/// Do-nothing destructor
~CmdLineOpts()125 	virtual ~CmdLineOpts () {
126 		trace_with_mask ("CmdLineOpts::~CmdLineOpts", CMDLINEOPTS);
127 	}
128 
129 	/** Add binary flag option.
130 	    @param c  short name
131 	    @param s  long name
132 	    @param f  pointer to bool flag variable
133 	    @return true on success, false on error
134 	*/
135 	bool add_flag_opt (const char c, const string& s, bool* f);
136 
137 	/** Add an option with STL string argument.
138 	    @param c  short name
139 	    @param s  long name
140 	    @param str  pointer to string variable
141 	    @return true on success, false on error
142 	*/
143 	bool add_opt (const char c, const string& s, string* str);
144 
145 	/** Add an option with integer argument.
146 	    @param c  short name
147 	    @param s  long name
148 	    @param i  pointer to int variable
149 	    @return true on success, false on error
150 	*/
151 	bool add_opt (const char c, const string& s, int* i);
152 
153 	/** Add an option with unsigned integer argument.
154 	    @param c  short name
155 	    @param s  long name
156 	    @param ui  pointer to u_int variable
157 	    @return true on success, false on error
158 	*/
159 	bool add_opt (const char c, const string& s, unsigned int* ui);
160 
161 	/** Add an option with long argument.
162 	    @param c  short name
163 	    @param s  long name
164 	    @param l  pointer to long variable
165 	    @return true on success, false on error
166 	*/
167 	bool add_opt (const char c, const string& s, long* l);
168 
169 	/** Add an option with unsigned long argument.
170 	    @param c  short name
171 	    @param s  long name
172 	    @param ul  pointer to unsigned long variable
173 	    @return true on success, false on error
174 	*/
175 	bool add_opt (const char c, const string& s, unsigned long* ul);
176 
177 	/** Add an option with double argument.
178 	    @param c  short name
179 	    @param s  long name
180 	    @param d  pointer to double variable
181 	    @return true on success, false on error
182 	*/
183 	bool add_opt (const char c, const string& s, double* d);
184 
185 	/** Add an option with float argument.
186 	    @param c  short name
187 	    @param s  long name
188 	    @param f  pointer to float variable
189 	    @return true on success, false on error
190 	*/
191 	bool add_opt (const char c, const string& s, float* f);
192 
193 	/** Add an option with static function argument.
194 	    This void function with no arguments will be called
195 	    when command line option is processed. An option installed
196 	    is treated as binary flag option.
197 
198 	    @param c_  short name
199 	    @param s_  long name
200 	    @param f_  pointer to the static function
201 
202 	    @return true on success, false on error
203 	*/
204 	bool add_opt (const char c_, const string& s_, OPTS_FUNC f_);
205 
206 	/** Add an option with static function argument.
207 	    This void function with STL string arguments will be called
208 	    when command line option is processed. The option value is
209 	    delivered via function's argument.
210 
211 	    @param c_  short name
212 	    @param s_  long name
213 	    @param f_  pointer to the static function
214 	    @return true on success, false on error
215 	*/
216 	bool add_opt (const char c_, const string& s_, OPTS_FUNC_ONE f_);
217 
218 	/** Remove option for the option list.
219 	    @param c_ short name
220 	    @param s_ long name
221 	    @return true if found, false if not
222 	*/
223 	bool rm_opt (const char c_, const string& s_);
224 
225 	/** Parse command line arguments based on installed options set.
226 	    @return true on success, false on error.
227 	*/
228 	bool parse_args (const char* argv[]);
229 
230 	/** Parse configuration parameters found in [options] section
231 		of the INI file. File should be already loaded with load().
232 
233 		@param inifile_ The INI file to parse.
234 		@return The number of options parsed or -1 if [options] section
235 		        is missing
236 	*/
237 	int parse_config_file (IniFile& inifile_);
238 
239 	/** If previous call to one of member functions returned false,
240 	    retrieve detailed error message.
241 	*/
242 	const char* get_opt_error () const;
243 
244 	/** Static function. Convert string list of command line options
245 	    into dynamically allocated argv-like array. The array is
246 	    terminated with NULL. This memory must be freed after it has
247 	    been used. Remember that the first parameter is process name.
248 	    @param src_  command line option string
249 	    @param argc_ number of options found in the source string
250 	    @param argv_ returns a pointer to the heap-allocated memory
251 	*/
252 	static void str_to_argv (const string& src_, int&  argc_, char**& argv_);
253 
254 	/** Free up memory allocated by <TT>str_to_argv()</TT> function	 */
255 	static void free_argv (char**& argv_);
256 
257 	/// Write options set to the log file.
258 	void dump () const;
259 
260 protected:
261 	/// Detect if supplied option is valid
262 	bool is_valid (const char sopt_, const string& lopt_);
263 
264 	/// Reset error message to an empty string
265 	void set_error_none ();
266 
267 	/** Perform value assignment to the node. Data conversion  happens here. */
268 	bool assign (Option* node_, const char* op_);
269 
270 	/// Locate option in the options set
271 	Option* find_option (const char* str_);
272 
273 	/// Locate option in the options set
274 	Option* find_option (const char letter_);
275 
276 	/** Process positional argument arg_. This method must be
277 	    overloaded by the derived class to take advantage of it.
278 	    @param arg_ positional argument value
279 	*/
280 	virtual void pos_arg (const char* arg_);
281 
282 private:
283 	/// Options set
284 	OptionSet m_opts_set;
285 
286 	/// Last reported error
287 	string    m_error;
288 };
289 
290 
291 inline void
pos_arg(const char *)292 CmdLineOpts::pos_arg (const char* /*arg_*/) { /* no-opt*/ }
293 
294 inline
CmdLineOpts()295 CmdLineOpts::CmdLineOpts () : m_opts_set (), m_error ("")
296 {
297 	trace_with_mask("CmdLineOpts::CmdLineOpts", CMDLINEOPTS);
298 	set_error_none ();
299 }
300 
301 inline void
set_error_none()302 CmdLineOpts::set_error_none ()
303 {
304 	trace_with_mask("CmdLineOpts::set_error_none", CMDLINEOPTS);
305 	m_error = "";
306 }
307 
308 inline const char*
get_opt_error()309 CmdLineOpts::get_opt_error () const
310 {
311 	return (m_error.c_str ());
312 }
313 
314 
315 } // end namespace ASSA
316 
317 #endif /* CMD_LINE_OPTS_H */
318