1 /* -*- related-file-name: "../../liblcdf/clp.c" -*- */
2 #ifndef LCDF_CLP_H
3 #define LCDF_CLP_H
4 #ifdef __cplusplus
5 extern "C" {
6 #endif
7 
8 /* clp.h - Public interface to CLP.
9  * This file is part of CLP, the command line parser package.
10  *
11  * Copyright (c) 1997-2017 Eddie Kohler, ekohler@gmail.com
12  *
13  * CLP is free software. It is distributed under the GNU General Public
14  * License, Version 2, or, alternatively and at your discretion, under the
15  * more permissive (BSD-like) Click LICENSE file as described below.
16  *
17  * Permission is hereby granted, free of charge, to any person obtaining a
18  * copy of this software and associated documentation files (the
19  * "Software"), to deal in the Software without restriction, subject to the
20  * conditions listed in the Click LICENSE file, which is available in full at
21  * http://github.com/kohler/click/blob/master/LICENSE. The conditions
22  * include: you must preserve this copyright notice, and you cannot mention
23  * the copyright holders in advertising related to the Software without
24  * their permission. The Software is provided WITHOUT ANY WARRANTY, EXPRESS
25  * OR IMPLIED. This notice is a summary of the Click LICENSE file; the
26  * license in that file is binding. */
27 
28 #include <stdio.h>
29 #include <stdarg.h>
30 
31 typedef struct Clp_Option Clp_Option;
32 typedef struct Clp_Parser Clp_Parser;
33 typedef struct Clp_ParserState Clp_ParserState;
34 
35 
36 /** @brief Option description.
37  *
38  * CLP users declare arrays of Clp_Option structures to specify what options
39  * should be parsed.
40  * @sa Clp_NewParser, Clp_SetOptions */
41 struct Clp_Option {
42     const char *long_name;	/**< Name of long option, or NULL if the option
43 				     has no long name. */
44     int short_name;		/**< Character defining short option, or 0 if
45 				     the option has no short name. */
46     int option_id;		/**< User-specified ID defining option,
47 				     returned by Clp_Next. */
48     int val_type;		/**< ID of option's value type, or 0 if option
49 				     takes no value. */
50     int flags;			/**< Option parsing flags. */
51 };
52 
53 /** @name Value types
54  * These values describe the type of an option's argument and are used in
55  * the Clp_Option val_type field.  For example, if an option took integers, its
56  * Clp_Option structure would have val_type set to Clp_ValInt. */
57 /**@{*/
58 #define Clp_NoVal		0	/**< @brief Option takes no value. */
59 #define Clp_ValString		1	/**< @brief Option value is an
60 					     arbitrary string. */
61 #define Clp_ValStringNotOption	2	/**< @brief Option value is a
62 					     non-option string.
63 
64 		See Clp_DisallowOptions. */
65 #define Clp_ValBool		3	/**< @brief Option value is a
66 					     boolean.
67 
68 		Accepts "true", "false", "yes", "no", "1", and "0", or any
69 		prefixes thereof.  The match is case-insensitive. */
70 #define Clp_ValInt		4	/**< @brief Option value is a
71 					     signed int.
72 
73 		Accepts an optional "+" or "-" sign, followed by one or more
74 		digits.  The digits may be include a "0x" or "0X" prefix, for
75 		a hexadecimal number, or a "0" prefix, for an octal number;
76 		otherwise it is decimal. */
77 #define Clp_ValUnsigned		5	/**< @brief Option value is an
78 					     unsigned int.
79 
80 		Accepts an optional "+" sign, followed by one or more
81 		digits.  The digits may be include a "0x" or "0X" prefix, for
82 		a hexadecimal number, or a "0" prefix, for an octal number;
83 		otherwise it is decimal. */
84 #define Clp_ValLong             6       /**< @brief Option value is a
85                                              signed long. */
86 #define Clp_ValUnsignedLong     7       /**< @brief Option value is an
87                                              unsigned long. */
88 #define Clp_ValDouble		8	/**< @brief Option value is a
89 					     double.
90 		Accepts a real number as defined by strtod(). */
91 #define Clp_ValFirstUser	10	/**< @brief Value types >=
92 					     Clp_ValFirstUser are available
93 					     for user types. */
94 /**@}*/
95 
96 /** @name Option flags
97  * These flags are used in the Clp_Option flags field. */
98 /**@{*/
99 #define Clp_Mandatory		(1<<0)	/**< @brief Option flag: value
100 					     is mandatory.
101 
102 		It is an error if the option has no value.  This is the
103 		default if an option has arg_type != 0 and the Clp_Optional
104 		flag is not provided. */
105 #define Clp_Optional		(1<<1)	/**< @brief Option flag: value
106 					     is optional. */
107 #define Clp_Negate		(1<<2)	/**< @brief Option flag: option
108 					     may be negated.
109 
110 		--no-[long_name] will be accepted in argument lists. */
111 #define Clp_OnlyNegated		(1<<3)	/**< @brief Option flag: option
112 					     <em>must</em> be negated.
113 
114 		--no-[long_name] will be accepted in argument lists, but
115 		--[long_name] will not.  This is the default if long_name
116 		begins with "no-". */
117 #define Clp_PreferredMatch	(1<<4)	/**< @brief Option flag: prefer this
118 					     option when matching.
119 
120 		Prefixes of --[long_name] should map to this option, even if
121 		other options begin with --[long_name]. */
122 /**@}*/
123 
124 /** @name Option character types
125  * These flags are used in to define character types in Clp_SetOptionChar(). */
126 /**@{*/
127 /*	Clp_NotOption		0 */
128 #define Clp_Short		(1<<0)	/**< @brief Option character begins
129 					     a set of short options. */
130 #define Clp_Long		(1<<1)	/**< @brief Option character begins
131 					     a long option. */
132 #define Clp_ShortNegated	(1<<2)	/**< @brief Option character begins
133 					     a set of negated short options. */
134 #define Clp_LongNegated		(1<<3)	/**< @brief Option character begins
135 					     a negated long option. */
136 #define Clp_LongImplicit	(1<<4)	/**< @brief Option character can begin
137 					     a long option, and is part of that
138 					     long option. */
139 /**@}*/
140 
141 #define Clp_NotOption		0	/**< @brief Clp_Next value: argument
142 					     was not an option. */
143 #define Clp_Done		-1	/**< @brief Clp_Next value: there are
144 					     no more arguments. */
145 #define Clp_BadOption		-2	/**< @brief Clp_Next value: argument
146 					     was an erroneous option. */
147 #define Clp_Error		-3	/**< @brief Clp_Next value: internal
148 					     CLP error. */
149 
150 #define Clp_ValSize		40	/**< @brief Minimum size of the
151 					     Clp_Parser val.cs field. */
152 #define Clp_ValIntSize		10	/**< @brief Minimum size of the
153 					     Clp_Parser val.is field. */
154 
155 
156 /** @brief A value parsing function.
157  * @param clp the parser
158  * @param vstr the value to be parsed
159  * @param complain if nonzero, report error messages via Clp_OptionError
160  * @param user_data user data passed to Clp_AddType()
161  * @return 1 if parsing succeeded, 0 otherwise
162  */
163 typedef int (*Clp_ValParseFunc)(Clp_Parser *clp, const char *vstr,
164 				int complain, void *user_data);
165 
166 /** @brief A function for reporting option errors.
167  * @param clp the parser
168  * @param message error message
169  */
170 typedef void (*Clp_ErrorHandler)(Clp_Parser *clp, const char *message);
171 
172 
173 /** @brief Command line parser.
174  *
175  * A Clp_Parser object defines an instance of CLP, including allowed options,
176  * value types, and current arguments.
177  * @sa Clp_NewParser, Clp_SetOptions, Clp_SetArguments */
178 struct Clp_Parser {
179     const Clp_Option *option;	/**< The last option. */
180 
181     int negated;		/**< Whether the last option was negated. */
182 
183     int have_val;		/**< Whether the last option had a value. */
184     const char *vstr;		/**< The string value provided with the last
185 				     option. */
186 
187     union {
188 	int i;
189 	unsigned u;
190         long l;
191         unsigned long ul;
192 	double d;
193 	const char *s;
194 	void *pv;
195 #ifdef HAVE_INT64_TYPES
196 	int64_t i64;
197 	uint64_t u64;
198 #endif
199 	char cs[Clp_ValSize];
200 	unsigned char ucs[Clp_ValSize];
201 	int is[Clp_ValIntSize];
202 	unsigned us[Clp_ValIntSize];
203     } val;			/**< The parsed value provided with the last
204 				     option. */
205 
206     void *user_data;		/**< Uninterpreted by CLP; users can set
207 				     arbitrarily. */
208 
209     struct Clp_Internal *internal;
210 };
211 
212 /** @cond never */
213 #if __GNUC__ >= 4
214 # define CLP_SENTINEL		__attribute__((sentinel))
215 #else
216 # define CLP_SENTINEL		/* nothing */
217 #endif
218 /** @endcond never */
219 
220 
221 /** @brief Create a new Clp_Parser. */
222 Clp_Parser *Clp_NewParser(int argc, const char * const *argv,
223 			  int nopt, const Clp_Option *opt);
224 
225 /** @brief Destroy a Clp_Parser object. */
226 void Clp_DeleteParser(Clp_Parser *clp);
227 
228 
229 /** @brief Return @a clp's program name. */
230 const char *Clp_ProgramName(Clp_Parser *clp);
231 
232 /** @brief Set @a clp's program name. */
233 const char *Clp_SetProgramName(Clp_Parser *clp, const char *name);
234 
235 
236 /** @brief Set @a clp's error handler function. */
237 Clp_ErrorHandler Clp_SetErrorHandler(Clp_Parser *clp, Clp_ErrorHandler errh);
238 
239 /** @brief Set @a clp's UTF-8 mode. */
240 int Clp_SetUTF8(Clp_Parser *clp, int utf8);
241 
242 /** @brief Return @a clp's treatment of character @a c. */
243 int Clp_OptionChar(Clp_Parser *clp, int c);
244 
245 /** @brief Set @a clp's treatment of character @a c. */
246 int Clp_SetOptionChar(Clp_Parser *clp, int c, int type);
247 
248 /** @brief Set @a clp's option definitions. */
249 int Clp_SetOptions(Clp_Parser *clp, int nopt, const Clp_Option *opt);
250 
251 /** @brief Set @a clp's arguments. */
252 void Clp_SetArguments(Clp_Parser *clp, int argc, const char * const *argv);
253 
254 /** @brief Set whether @a clp is searching for options. */
255 int Clp_SetOptionProcessing(Clp_Parser *clp, int on);
256 
257 
258 #define Clp_DisallowOptions	(1<<0)	/**< @brief Value type flag: value
259 					     can't be an option string.
260 
261 		See Clp_AddType(). */
262 
263 /** @brief Define a new value type for @a clp. */
264 int Clp_AddType(Clp_Parser *clp, int val_type, int flags,
265 		Clp_ValParseFunc parser, void *user_data);
266 
267 
268 #define Clp_AllowNumbers	(1<<0)	/**< @brief String list flag: allow
269 					     explicit numbers.
270 
271 		See Clp_AddStringListType() and Clp_AddStringListTypeVec(). */
272 #define Clp_StringListLong      (1<<1)  /**< @brief String list flag: values
273                                              have long type. */
274 
275 /** @brief Define a new string list value type for @a clp. */
276 int Clp_AddStringListTypeVec(Clp_Parser *clp, int val_type, int flags,
277 			     int nstrs, const char * const *strs,
278 			     const int *vals);
279 
280 /** @brief Define a new string list value type for @a clp. */
281 int Clp_AddStringListType(Clp_Parser *clp, int val_type, int flags, ...)
282 			  CLP_SENTINEL;
283 
284 
285 /** @brief Parse and return the next argument from @a clp. */
286 int Clp_Next(Clp_Parser *clp);
287 
288 /** @brief Return the next argument from @a clp without option parsing. */
289 const char *Clp_Shift(Clp_Parser *clp, int allow_options);
290 
291 
292 /** @brief Create a new Clp_ParserState. */
293 Clp_ParserState *Clp_NewParserState(void);
294 
295 /** @brief Destroy a Clp_ParserState object. */
296 void Clp_DeleteParserState(Clp_ParserState *state);
297 
298 /** @brief Save @a clp's current state in @a state. */
299 void Clp_SaveParser(const Clp_Parser *clp, Clp_ParserState *state);
300 
301 /** @brief Restore parser state from @a state into @a clp. */
302 void Clp_RestoreParser(Clp_Parser *clp, const Clp_ParserState *state);
303 
304 
305 /** @brief Report a parser error. */
306 int Clp_OptionError(Clp_Parser *clp, const char *format, ...);
307 
308 /** @brief Format a message. */
309 int Clp_vsnprintf(Clp_Parser* clp, char* str, size_t size,
310                   const char* format, va_list val);
311 
312 /** @brief Print a message. */
313 int Clp_fprintf(Clp_Parser* clp, FILE* f, const char* format, ...);
314 
315 /** @brief Print a message. */
316 int Clp_vfprintf(Clp_Parser* clp, FILE* f, const char* format, va_list val);
317 
318 /** @brief Extract the current option as a string. */
319 int Clp_CurOptionNameBuf(Clp_Parser *clp, char *buf, int len);
320 
321 /** @brief Extract the current option as a string. */
322 const char *Clp_CurOptionName(Clp_Parser *clp);
323 
324 /** @brief Test if the current option had long name @a name. */
325 int Clp_IsLong(Clp_Parser *clp, const char *long_name);
326 
327 /** @brief Test if the current option had short name @a name. */
328 int Clp_IsShort(Clp_Parser *clp, int short_name);
329 
330 #undef CLP_SENTINEL
331 #ifdef __cplusplus
332 }
333 #endif
334 #endif
335