1 /* Licensed under GPLv3+ - see LICENSE file for details */
2 #include <ccan/opt/opt.h>
10 /* Upper bound to sprintf this simple type? Each 3 bits < 1 digit. */
11 #define CHAR_SIZE(type) (((sizeof(type)*CHAR_BIT + 2) / 3) + 1)
13 /* FIXME: asprintf module? */
14 static char *arg_bad(const char *fmt, const char *arg)
16 char *str = malloc(strlen(fmt) + strlen(arg));
17 sprintf(str, fmt, arg);
21 char *opt_set_bool(bool *b)
27 char *opt_set_invbool(bool *b)
33 char *opt_set_bool_arg(const char *arg, bool *b)
35 if (!strcasecmp(arg, "yes") || !strcasecmp(arg, "true"))
36 return opt_set_bool(b);
37 if (!strcasecmp(arg, "no") || !strcasecmp(arg, "false"))
38 return opt_set_invbool(b);
40 return opt_invalid_argument(arg);
43 char *opt_set_invbool_arg(const char *arg, bool *b)
45 char *err = opt_set_bool_arg(arg, b);
53 char *opt_set_charp(const char *arg, char **p)
59 /* Set an integer value, various forms.
60 FIXME: set to 1 on arg == NULL ? */
61 char *opt_set_intval(const char *arg, int *i)
64 char *err = opt_set_longval(arg, &l);
69 /* Beware truncation... */
71 return arg_bad("value '%s' does not fit into an integer", arg);
75 char *opt_set_uintval(const char *arg, unsigned int *ui)
78 char *err = opt_set_intval(arg, &i);
83 return arg_bad("'%s' is negative but destination is unsigned", arg);
88 char *opt_set_longval(const char *arg, long *l)
92 /* This is how the manpage says to do it. Yech. */
94 *l = strtol(arg, &endp, 0);
96 return arg_bad("'%s' is not a number", arg);
98 return arg_bad("'%s' is out of range", arg);
102 char *opt_set_ulongval(const char *arg, unsigned long *ul)
107 err = opt_set_longval(arg, &l);
112 return arg_bad("'%s' is negative but destination is unsigned", arg);
116 char *opt_inc_intval(int *i)
122 /* Display version string. */
123 char *opt_version_and_exit(const char *version)
125 printf("%s\n", version);
129 char *opt_usage_and_exit(const char *extra)
131 printf("%s", opt_usage(opt_argv0, extra));
135 void opt_show_bool(char buf[OPT_SHOW_LEN], const bool *b)
137 strncpy(buf, *b ? "true" : "false", OPT_SHOW_LEN);
140 void opt_show_invbool(char buf[OPT_SHOW_LEN], const bool *b)
142 strncpy(buf, *b ? "false" : "true", OPT_SHOW_LEN);
145 void opt_show_charp(char buf[OPT_SHOW_LEN], char *const *p)
147 size_t len = strlen(*p);
149 if (len > OPT_SHOW_LEN - 2)
150 len = OPT_SHOW_LEN - 2;
151 strncpy(buf+1, *p, len);
153 if (len < OPT_SHOW_LEN - 2)
157 /* Show an integer value, various forms. */
158 void opt_show_intval(char buf[OPT_SHOW_LEN], const int *i)
160 snprintf(buf, OPT_SHOW_LEN, "%i", *i);
163 void opt_show_uintval(char buf[OPT_SHOW_LEN], const unsigned int *ui)
165 snprintf(buf, OPT_SHOW_LEN, "%u", *ui);
168 void opt_show_longval(char buf[OPT_SHOW_LEN], const long *l)
170 snprintf(buf, OPT_SHOW_LEN, "%li", *l);
173 void opt_show_ulongval(char buf[OPT_SHOW_LEN], const unsigned long *ul)
175 snprintf(buf, OPT_SHOW_LEN, "%lu", *ul);
178 /* a helper function that multiplies out an argument's kMGTPE suffix in the
179 * long long int range, and perform checks common to all integer destinations.
181 * The base will be either 1000 or 1024, corresponding with the '_si' and
185 static char *set_llong_with_suffix(const char *arg, long long *ll,
186 const long long base)
190 return arg_bad("'%s' (an empty string) is not a number", arg);
193 *ll = strtoll(arg, &endp, 0);
195 return arg_bad("'%s' is out of range", arg);
197 /*The string continues with non-digits. If there is just one
198 letter and it is a known multiplier suffix, use it.*/
200 return arg_bad("'%s' is not a number (suffix too long)", arg);
213 mul = base * base * base;
217 mul = base * base * base * base;
220 mul = base * base * base * base * base;
223 mul = base * base * base * base * base * base;
225 /* This is as far as we can go in 64 bits ('E' is 2 ^ 60) */
227 return arg_bad("'%s' is not a number (unknown suffix)",
230 if (*ll > LLONG_MAX / mul || *ll < LLONG_MIN / mul)
231 return arg_bad("'%s' is out of range", arg);
237 /* Middle layer helpers that perform bounds checks for specific target sizes
240 static char * set_ulonglong_with_suffix(const char *arg, unsigned long long *ull,
244 char *err = set_llong_with_suffix(arg, &ll, base);
248 return arg_bad("'%s' is negative but destination is unsigned", arg);
253 static char * set_long_with_suffix(const char *arg, long *l, const long base)
256 char *err = set_llong_with_suffix(arg, &ll, base);
257 if (err != NULL) /*an error*/
262 return arg_bad("value '%s' does not fit into a long", arg);
266 static char * set_ulong_with_suffix(const char *arg, unsigned long *ul, const long base)
269 char *err = set_llong_with_suffix(arg, &ll, base);
273 return arg_bad("'%s' is negative but destination is unsigned", arg);
276 return arg_bad("value '%s' does not fit into an unsigned long", arg);
280 static char * set_int_with_suffix(const char *arg, int *i, const long base)
283 char *err = set_llong_with_suffix(arg, &ll, base);
284 if (err != NULL) /*an error*/
289 return arg_bad("value '%s' does not fit into an int", arg);
293 static char * set_uint_with_suffix(const char *arg, unsigned int *u, const long base)
296 char *err = set_llong_with_suffix(arg, &ll, base);
300 return arg_bad("'%s' is negative but destination is unsigned", arg);
303 return arg_bad("value '%s' does not fit into an unsigned int", arg);
307 /*Set an integer, with decimal or binary suffixes.
308 The accepted suffixes are k/K, M/m, G/g, T, P, E.
310 The *_bi functions multiply the numeric value by a power of 1024, while the
311 *_si functions multiply by a power of 1000.
314 char * opt_set_ulonglongval_bi(const char *arg, unsigned long long *ll)
316 return set_ulonglong_with_suffix(arg, ll, 1024);
319 char * opt_set_ulonglongval_si(const char *arg, unsigned long long *ll)
321 return set_ulonglong_with_suffix(arg, ll, 1000);
324 char * opt_set_longlongval_bi(const char *arg, long long *ll)
326 return set_llong_with_suffix(arg, ll, 1024);
329 char * opt_set_longlongval_si(const char *arg, long long *ll)
331 return set_llong_with_suffix(arg, ll, 1000);
334 char * opt_set_longval_bi(const char *arg, long *l)
336 return set_long_with_suffix(arg, l, 1024);
339 char * opt_set_longval_si(const char *arg, long *l)
341 return set_long_with_suffix(arg, l, 1000);
344 char * opt_set_ulongval_bi(const char *arg, unsigned long *ul)
346 return set_ulong_with_suffix(arg, ul, 1024);
349 char * opt_set_ulongval_si(const char *arg, unsigned long *ul)
351 return set_ulong_with_suffix(arg, ul, 1000);
354 char * opt_set_intval_bi(const char *arg, int *i)
356 return set_int_with_suffix(arg, i, 1024);
359 char * opt_set_intval_si(const char *arg, int *i)
361 return set_int_with_suffix(arg, i, 1000);
364 char * opt_set_uintval_bi(const char *arg, unsigned int *u)
366 return set_uint_with_suffix(arg, u, 1024);
369 char * opt_set_uintval_si(const char *arg, unsigned int *u)
371 return set_uint_with_suffix(arg, u, 1000);