Mstdlib-1.24.0
m_getopt.h
1/* The MIT License (MIT)
2 *
3 * Copyright (c) 2015 Monetra Technologies, LLC.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the "Software"), to deal
7 * in the Software without restriction, including without limitation the rights
8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 * THE SOFTWARE.
22 */
23
24#ifndef __M_GETOPT_H__
25#define __M_GETOPT_H__
26
27/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
28
29#include <mstdlib/base/m_defs.h>
30#include <mstdlib/base/m_types.h>
31
32/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
33
34__BEGIN_DECLS
35
36/*! \addtogroup m_getopt getopt
37 * \ingroup mstdlib_base
38 *
39 * Command line argument parsing.
40 *
41 * Handles parsing using a series of provided callbacks for each type. Auto
42 * conversion of the argument for the option type will take place. Callbacks
43 * are allowed to reject the option or argument. This will stop parsing.
44 *
45 * If auto conversion is unwanted use the string option type. String options
46 * will alway shave their arguments passed unmodified.
47 *
48 * Options can be marked as having required or optional arguments.
49 *
50 * The boolean type is somewhat special. If marked as not having a required
51 * argument it is treated as a flag. For example -b would call the boolean
52 * callback with a value of M_TRUE. If a boolean is marked as val required
53 * then a value is required and the result of conversion (using M_str_istrue)
54 * will be passed to the callback.
55 *
56 * For options that should _not_ have an argument use the boolean type with
57 * val not required.
58 *
59 * Option callbacks are only called when an option is specified. Meaning for
60 * boolean options a value of M_FALSE will only be sent if the option was
61 * explcitly used and set to false.
62 *
63 * Supports auto generation of help message.
64 *
65 * Valid characters for options (short/long) is all ASCII printable [!-~] except:
66 * - space
67 * - '-' (short or start/end long)
68 * - '='
69 * - '"'
70 * - '''
71 *
72 * To stop option processing and treat all following values as nonoptions use --
73 * as an option.
74 *
75 * An optional thunk can be passed in during parsing which will be passed to all
76 * callbacks. This can be used to collect all options into an object instead of
77 * stored in global variables.
78 *
79 * Option callbacks will receive the short and long options associated with the
80 * option. If no short option was set the short_opt callback value will be 0.
81 * If no long option was set the long_opt callback value will be NULL.
82 *
83 * Example:
84 *
85 * \code{.c}
86 * static M_bool nonopt_cb(size_t idx, const char *option, void *thunk)
87 * {
88 * M_printf("option='%s'\n", option);
89 * }
90 *
91 * static M_bool int_cb(char short_opt, const char *long_opt, M_int64 *integer, void *thunk)
92 * {
93 * M_printf("short_opt='%d', long_opt='%s', integer='%lld'\n", short_opt, long_opt, integer!=NULL?*integer:-1);
94 * }
95 *
96 * int main(int argc, char **argv) {
97 * M_getopt_t *g;
98 * char *help;
99 * const char *fail;
100 *
101 * g = M_getopt_create(nonopt_cb);
102 * M_getopt_addinteger(g, 'i', "i1", M_TRUE, "DESCR 1", int_cb);
103 *
104 * help = M_getopt_help(g);
105 * M_printf("help=\n%s\n", help);
106 * M_free(help);
107 *
108 * if (M_getopt_parse(g, argv, argc, &fail, NULL) == M_GETOPT_ERROR_SUCCESS) {
109 * M_printf("Options parsed successfully\n");
110 * } else {
111 * M_printf("Options parse error: %s\n", fail);
112 * }
113 *
114 * M_getopt_destroy(g);
115 * return 0;
116 * }
117 * \endcode
118 *
119 * @{
120 */
121
122struct M_getopt;
123typedef struct M_getopt M_getopt_t;
124
125
126/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
127
128/*! Error codes. */
129typedef enum {
137
138
139/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
140
141/*! Callback for non-option parameters */
142typedef M_bool (*M_getopt_nonopt_cb)(size_t idx, const char *option, void *thunk);
143
144
145/*! Callback for integer data type */
146typedef M_bool (*M_getopt_integer_cb)(char short_opt, const char *long_opt, M_int64 *integer, void *thunk);
147
148
149/*! Callback for decimal data type */
150typedef M_bool (*M_getopt_decimal_cb)(char short_opt, const char *long_opt, M_decimal_t *decimal, void *thunk);
151
152
153/*! Callback for string data type */
154typedef M_bool (*M_getopt_string_cb)(char short_opt, const char *long_opt, const char *string, void *thunk);
155
156
157/*! Callback for boolean data type */
158typedef M_bool (*M_getopt_boolean_cb)(char short_opt, const char *long_opt, M_bool boolean, void *thunk);
159
160
161/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
162
163/*! Create a new getopt object.
164 *
165 * \param cb Callback to be called with non-option parameters. NULL if non-option parameters are not allowed.
166 *
167 * \return Getopt object.
168 */
170
171
172/*! Destroy a getopt object
173 *
174 * \param[in] g Getopt object to destroy.
175 */
177
178
179/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
180
181/*! Output help text for command line options.
182 *
183 * Components:
184 * <val> value is required
185 * [val] value is optional
186 * -s short option
187 * --long long option
188 * (type) Type such as integer, decimal ... Type will not be printed for boolean options.
189 * Description Text description about the option
190 *
191 * Example:
192 * \code -s <val> (type) Description \endcode
193 * \code --long [val] (type) \endcode
194 * \code -s, --long [val] (type) Description \endcode
195 * \code -s Description \endcode
196 *
197 * \param[in] g Getopt object.
198 */
199M_API char *M_getopt_help(const M_getopt_t *g);
200
201
202/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
203
204/*! Add an integer parameter.
205 *
206 * \param[in] g Getopt object
207 * \param[in] short_opt Short option, must be alpha-numeric, case-sensitive. Pass 0 if not used
208 * \param[in] long_opt Long option name, must be alpha-numeric or hyphens, case-insensitive. Can not start or end
209 * with hyphens. Pass NULL if not used.
210 * \param[in] val_required Whether or not the option requires a value.
211 * \param[in] description Field description. Used with output putting help message.
212 * \param[in] cb Callback to call with value. NULL will be passed if no value provided
213 *
214 * \return M_TRUE on success, M_FALSE on failure.
215 */
216M_API M_bool M_getopt_addinteger(M_getopt_t *g, char short_opt, const char *long_opt, M_bool val_required, const char *description, M_getopt_integer_cb cb);
217
218
219/*! Add a decimal parameter.
220 *
221 * \param[in] g Getopt object
222 * \param[in] short_opt Short option, must be alpha-numeric, case-sensitive. Pass 0 if not used
223 * \param[in] long_opt Long option name, must be alpha-numeric or hyphens, case-insensitive. Can not start or end
224 * with hyphens. Pass NULL if not used.
225 * \param[in] val_required Whether or not the option requires a value.
226 * \param[in] description Field description. Used with output putting help message.
227 * \param[in] cb Callback to call with value. NULL will be passed if no value provided
228 *
229 * \return M_TRUE on success, M_FALSE on failure.
230 */
231M_API M_bool M_getopt_adddecimal(M_getopt_t *g, char short_opt, const char *long_opt, M_bool val_required, const char *description, M_getopt_decimal_cb cb);
232
233
234/*! Add a string parameter.
235 *
236 * \param[in] g Getopt object
237 * \param[in] short_opt Short option, must be alpha-numeric, case-sensitive. Pass 0 if not used
238 * \param[in] long_opt Long option name, must be alpha-numeric or hyphens, case-insensitive. Can not start or end
239 * with hyphens. Pass NULL if not used.
240 * \param[in] val_required Whether or not the option requires a value.
241 * \param[in] description Field description. Used with output putting help message.
242 * \param[in] cb Callback to call with value. NULL will be passed if no value provided
243 *
244 * \return M_TRUE on success, M_FALSE on failure.
245 */
246M_API M_bool M_getopt_addstring(M_getopt_t *g, char short_opt, const char *long_opt, M_bool val_required, const char *description, M_getopt_string_cb cb);
247
248
249/*! Add a boolean parameter.
250 *
251 * \param[in] g Getopt object
252 * \param[in] short_opt Short option, must be alpha-numeric, case-sensitive. Pass 0 if not used
253 * \param[in] long_opt Long option name, must be alpha-numeric or hyphens, case-insensitive. Can not start or end
254 * with hyphens. Pass NULL if not used.
255 * \param[in] val_required Whether or not the option requires a value. If M_FALSE this is treated as a flag and will be
256 * treated as M_TRUE in the value of the callback. If M_FALSE a value cannot be provided.
257 * \param[in] description Field description. Used with output putting help message.
258 * \param[in] cb Callback to call with value. Value will be M_TRUE if no value provided. Considered a
259 * flag enabling in this case.
260 *
261 * \return M_TRUE on success, M_FALSE on failure.
262 */
263M_API M_bool M_getopt_addboolean(M_getopt_t *g, char short_opt, const char *long_opt, M_bool val_required, const char *description, M_getopt_boolean_cb cb);
264
265
266/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
267
268/*! Parse command line arguments.
269 *
270 * \param[in] g Getopt object
271 * \param[in] argv Array of arguments. Will not be modified.
272 * \param[in] argc Number of arguments.
273 * \param[in] opt_fail On failure will have the argument that caused the failure.
274 * \param[in] thunk Thunk that will be passed to callbacks.
275 *
276 * \return Result.
277 */
278M_API M_getopt_error_t M_getopt_parse(const M_getopt_t *g, const char * const *argv, int argc, const char **opt_fail, void *thunk);
279
280/*! @} */
281
282__END_DECLS
283
284#endif /* __GETOPT_H__ */
Definition: m_decimal.h:78
void M_getopt_destroy(M_getopt_t *g)
struct M_getopt M_getopt_t
Definition: m_getopt.h:123
M_getopt_error_t
Definition: m_getopt.h:129
M_bool M_getopt_addboolean(M_getopt_t *g, char short_opt, const char *long_opt, M_bool val_required, const char *description, M_getopt_boolean_cb cb)
M_bool M_getopt_addstring(M_getopt_t *g, char short_opt, const char *long_opt, M_bool val_required, const char *description, M_getopt_string_cb cb)
M_bool(* M_getopt_string_cb)(char short_opt, const char *long_opt, const char *string, void *thunk)
Definition: m_getopt.h:154
M_bool(* M_getopt_decimal_cb)(char short_opt, const char *long_opt, M_decimal_t *decimal, void *thunk)
Definition: m_getopt.h:150
M_getopt_error_t M_getopt_parse(const M_getopt_t *g, const char *const *argv, int argc, const char **opt_fail, void *thunk)
M_bool M_getopt_adddecimal(M_getopt_t *g, char short_opt, const char *long_opt, M_bool val_required, const char *description, M_getopt_decimal_cb cb)
M_bool(* M_getopt_nonopt_cb)(size_t idx, const char *option, void *thunk)
Definition: m_getopt.h:142
M_bool(* M_getopt_integer_cb)(char short_opt, const char *long_opt, M_int64 *integer, void *thunk)
Definition: m_getopt.h:146
char * M_getopt_help(const M_getopt_t *g)
M_bool M_getopt_addinteger(M_getopt_t *g, char short_opt, const char *long_opt, M_bool val_required, const char *description, M_getopt_integer_cb cb)
M_getopt_t * M_getopt_create(M_getopt_nonopt_cb cb)
M_bool(* M_getopt_boolean_cb)(char short_opt, const char *long_opt, M_bool boolean, void *thunk)
Definition: m_getopt.h:158
@ M_GETOPT_ERROR_INVALIDDATATYPE
Definition: m_getopt.h:132
@ M_GETOPT_ERROR_MISSINGVALUE
Definition: m_getopt.h:134
@ M_GETOPT_ERROR_INVALIDOPT
Definition: m_getopt.h:131
@ M_GETOPT_ERROR_INVALIDORDER
Definition: m_getopt.h:133
@ M_GETOPT_ERROR_NONOPTION
Definition: m_getopt.h:135
@ M_GETOPT_ERROR_SUCCESS
Definition: m_getopt.h:130