1 /* COPYING ******************************************************************
2 For copyright and licensing terms, see the file named COPYING.
3 // **************************************************************************
4 */
5 
6 #if !defined(INCLUDE_POPT_H)
7 #define INCLUDE_POPT_H
8 
9 #include <vector>
10 #include <list>
11 #include <string>
12 #include <cstdio>
13 
14 namespace popt {
15 	struct error {
errorerror16 		error(const char * a, const char * m) : arg(a), msg(m) {}
17 		const char * arg, * msg;
18 	};
19 	class processor;
20 	struct definition {
21 	public:
definitiondefinition22 		definition() {}
23 		virtual bool execute(processor &, char c) = 0;
24 		virtual bool execute(processor &, char c, const char * s) = 0;
25 		virtual bool execute(processor &, const char * s) = 0;
26 		virtual ~definition() = 0;
27 	};
28 	class processor {
29 	public:
30 		processor(const char * n, definition & d, std::vector<const char *> & f);
~processor()31 		virtual ~processor() {}
32 		virtual const char * next_arg() = 0;
33 		void process(bool strictly_options_before_arguments, bool single_dash_long_options = false) {
34 			while (const char * arg = next_arg()) {
35 				if (is_stopped) break;
36 				if (0 == slash && ('-' == arg[0]
37 #if defined(__OS2__) || defined(__WIN32__) || defined(__NT__)
38 						|| '/' == arg[0]	// If the compiler is hosted on these platforms, this can also be the option character.
39 #endif
40 				))
41 					slash = arg[0];
42 				if (!slash || slash != arg[0]) {
43 					file_vector.push_back(arg);
44 					if (strictly_options_before_arguments)
45 						slash = EOF;
46 				} else if (arg[1] == slash) {
47 					if (!arg[2])
48 						slash = EOF;
49 					else if (!def.execute(*this, arg + 2))
50 						throw error(arg, "unrecognized option");
51 				} else if (!single_dash_long_options || !def.execute(*this, arg + 1)) {
52 					for ( const char * p(arg + 1); *p; ++p ) {
53 						if (def.execute(*this, *p, p + 1))
54 							break;
55 						if (!def.execute(*this, *p))
56 							throw error(arg, "unrecognized option(s)");
57 					}
58 				}
59 			}
60 		}
stopped()61 		bool stopped() const { return is_stopped; }
stop()62 		void stop() { is_stopped = true; }
63 		std::vector<const char *> & file_vector;
64 		const char * name;
65 	protected:
66 		int slash;
67 		definition & def;
68 		bool is_stopped;
69 	};
70 	template <class InputIterator> class arg_processor : public processor {
71 	public:
arg_processor(InputIterator b,InputIterator e,const char * n,definition & d,std::vector<const char * > & f)72 		arg_processor(InputIterator b, InputIterator e, const char * n, definition & d, std::vector<const char *> & f) : processor(n, d, f), current(b), end(e) {}
next_arg()73 		const char * next_arg()
74 		{
75 			if (current >= end) return nullptr;
76 			return *current++;
77 		}
78 	protected:
79 		InputIterator current, end;
80 	};
81 	struct table_definition : public definition {
82 	public:
table_definitiontable_definition83 		table_definition(unsigned c, definition * const * v, const char * d) : definition(), count(c), array(v), description(d) {}
84 		virtual void long_usage();
85 		virtual void help();
86 		virtual ~table_definition();
87 	protected:
88 		virtual bool execute(processor &, char c);
89 		virtual bool execute(processor &, char c, const char * s);
90 		virtual bool execute(processor &, const char * s);
91 		void gather_combining_shorts(std::string &);
92 		unsigned count;
93 		definition *  const *array;
94 		const char * description;
95 	};
96 	struct top_table_definition : public table_definition {
97 	public:
top_table_definitiontop_table_definition98 		top_table_definition(unsigned c, definition * const * v, const char * d, const char * a) : table_definition(c, v, d), arguments_description(a) {}
99 		virtual ~top_table_definition();
100 	protected:
101 		void do_usage(processor &);
102 		void do_help(processor &);
103 		const char * arguments_description;
104 		using table_definition::execute;
105 		virtual bool execute(processor &, char c);
106 		virtual bool execute(processor &, const char * s);
107 	};
108 	struct named_definition : public definition {
109 	public:
named_definitionnamed_definition110 		named_definition(char s, const char * l, const char * a, const char * d) : short_name(s), long_name(l), optarg_description(a), description(d) {}
query_args_descriptionnamed_definition111 		const char * query_args_description() const { return optarg_description; }
query_descriptionnamed_definition112 		const char * query_description() const { return description; }
query_short_namenamed_definition113 		char query_short_name() const { return short_name; }
query_long_namenamed_definition114 		const char * query_long_name() const { return long_name; }
115 		virtual ~named_definition() = 0;
116 	protected:
117 		char short_name;
118 		const char * long_name;
119 		const char * optarg_description;
120 		const char * description;
121 	};
122 	struct simple_named_definition : public named_definition {
123 	public:
simple_named_definitionsimple_named_definition124 		simple_named_definition(char s, const char * l, const char * d) : named_definition(s, l, nullptr, d) {}
125 		virtual ~simple_named_definition() = 0;
126 	protected:
127 		virtual void action(processor &) = 0;
128 		virtual bool execute(processor & proc, char c);
129 		virtual bool execute(processor &, char c, const char * s);
130 		virtual bool execute(processor & proc, const char * s);
131 	};
132 	struct compound_named_definition : public named_definition {
133 	public:
compound_named_definitioncompound_named_definition134 		compound_named_definition(char s, const char * l, const char * a, const char * d) : named_definition(s, l, a, d) {}
135 		virtual ~compound_named_definition() = 0;
136 	protected:
137 		virtual void action(processor &, const char *) = 0;
138 		virtual bool execute(processor & proc, char c);
139 		virtual bool execute(processor &, char c, const char * s);
140 		virtual bool execute(processor & proc, const char * s);
141 	};
142 	struct string_definition : public compound_named_definition {
143 	public:
string_definitionstring_definition144 		string_definition(char s, const char * l, const char * a, const char * d, const char * & v) : compound_named_definition(s, l, a, d), value(v) {}
145 		virtual ~string_definition();
146 	protected:
147 		virtual void action(processor &, const char *);
148 		const char * & value;
149 	};
150 	struct string_list_definition : public compound_named_definition {
151 	public:
152 		typedef std::list<std::string> list_type;
string_list_definitionstring_list_definition153 		string_list_definition(char s, const char * l, const char * a, const char * d, list_type & v) : compound_named_definition(s, l, a, d), value_list(v) {}
154 		virtual ~string_list_definition();
155 	protected:
156 		virtual void action(processor &, const char *);
157 		list_type & value_list;
158 	};
159 	struct bool_definition : public simple_named_definition {
160 	public:
bool_definitionbool_definition161 		bool_definition(char s, const char * l, const char * d, bool & v) : simple_named_definition(s, l, d), value(v) {}
162 		virtual ~bool_definition();
163 	protected:
164 		virtual void action(processor &);
165 		bool & value;
166 	};
167 	struct integral_definition : public compound_named_definition {
168 	public:
integral_definitionintegral_definition169 		integral_definition(char s, const char * l, const char * a, const char * d) : compound_named_definition(s, l, a, d), set(false) {}
170 		virtual ~integral_definition() = 0;
is_setintegral_definition171 		bool is_set() const { return set; }
172 	protected:
173 		bool set;
174 	};
175 	struct bool_string_definition : public integral_definition {
176 	public:
bool_string_definitionbool_string_definition177 		bool_string_definition(char s, const char * l, const char * d, bool & v) : integral_definition(s, l, a, d), value(v) {}
178 		virtual ~bool_string_definition();
179 	protected:
180                 static const char a[];
181 		virtual void action(processor &, const char *);
182 		bool & value;
183 	};
184 	struct number_definition : public integral_definition {
185 	public:
number_definitionnumber_definition186 		number_definition(char s, const char * l, const char * a, const char * d, int b) : integral_definition(s, l, a, d), base(b) {}
187 	protected:
188 		virtual void action(processor &, const char *) = 0;
189 		int base;
190 	};
191 	struct unsigned_number_definition : public number_definition {
192 	public:
unsigned_number_definitionunsigned_number_definition193 		unsigned_number_definition(char s, const char * l, const char * a, const char * d, unsigned long & v, int b) : number_definition(s, l, a, d, b), value(v) {}
194 		virtual ~unsigned_number_definition();
195 	protected:
196 		virtual void action(processor &, const char *);
197 		unsigned long & value;
198 	};
199 	struct signed_number_definition : public number_definition {
200 	public:
signed_number_definitionsigned_number_definition201 		signed_number_definition(char s, const char * l, const char * a, const char * d, signed long & v, int b) : number_definition(s, l, a, d, b), value(v) {}
202 		virtual ~signed_number_definition();
203 	protected:
204 		virtual void action(processor &, const char *);
205 		signed long & value;
206 	};
207 	struct compound_2arg_named_definition : public named_definition {
208 	public:
compound_2arg_named_definitioncompound_2arg_named_definition209 		compound_2arg_named_definition(char s, const char * l, const char * a, const char * d) : named_definition(s, l, a, d) {}
210 		virtual ~compound_2arg_named_definition() = 0;
211 	protected:
212 		virtual void action(processor &, const char *, const char *) = 0;
213 		virtual bool execute(processor & proc, char c);
214 		virtual bool execute(processor &, char c, const char * s);
215 		virtual bool execute(processor & proc, const char * s);
216 	};
217 	struct string_pair_definition : public compound_2arg_named_definition {
218 	public:
string_pair_definitionstring_pair_definition219 		string_pair_definition(char s, const char * l, const char * a, const char * d, const char * & v1, const char * & v2) : compound_2arg_named_definition(s, l, a, d), value1(v1), value2(v2) {}
220 		virtual ~string_pair_definition();
221 	protected:
222 		virtual void action(processor &, const char *, const char *);
223 		const char * & value1, * & value2;
224 	};
225 	struct string_pair_list_definition : public compound_2arg_named_definition {
226 	public:
227 		typedef std::pair<std::string,std::string> pair_type;
228 		typedef std::list<pair_type> list_type;
string_pair_list_definitionstring_pair_list_definition229 		string_pair_list_definition(char s, const char * l, const char * a, const char * d, list_type & v) : compound_2arg_named_definition(s, l, a, d), value_list(v) {}
230 		virtual ~string_pair_list_definition();
231 	protected:
232 		virtual void action(processor &, const char *, const char *);
233 		list_type & value_list;
234 	};
235 }
236 
237 #endif
238