1 /* Licensed under GPLv3+ - see LICENSE file for details */
2 #include <ccan/opt/opt.h>
3 #include <ccan/cast/cast.h>
11 /* Upper bound to sprintf this simple type? Each 3 bits < 1 digit. */
12 #define CHAR_SIZE(type) (((sizeof(type)*CHAR_BIT + 2) / 3) + 1)
14 /* FIXME: asprintf module? */
15 static char *arg_bad(const char *fmt, const char *arg)
17 char *str = malloc(strlen(fmt) + strlen(arg));
18 sprintf(str, fmt, arg);
22 char *opt_set_bool(bool *b)
28 char *opt_set_invbool(bool *b)
34 char *opt_set_bool_arg(const char *arg, bool *b)
36 if (!strcasecmp(arg, "yes") || !strcasecmp(arg, "true"))
37 return opt_set_bool(b);
38 if (!strcasecmp(arg, "no") || !strcasecmp(arg, "false"))
39 return opt_set_invbool(b);
41 return opt_invalid_argument(arg);
44 char *opt_set_invbool_arg(const char *arg, bool *b)
46 char *err = opt_set_bool_arg(arg, b);
54 char *opt_set_charp(const char *arg, char **p)
56 *p = cast_const(char *, arg);
60 /* Set an integer value, various forms.
61 FIXME: set to 1 on arg == NULL ? */
62 char *opt_set_intval(const char *arg, int *i)
65 char *err = opt_set_longval(arg, &l);
70 /* Beware truncation, but don't generate untestable code. */
71 if (sizeof(*i) != sizeof(l) && *i != l)
72 return arg_bad("value '%s' does not fit into an integer", arg);
76 char *opt_set_uintval(const char *arg, unsigned int *ui)
79 char *err = opt_set_intval(arg, &i);
84 return arg_bad("'%s' is negative but destination is unsigned", arg);
89 char *opt_set_longval(const char *arg, long *l)
93 /* This is how the manpage says to do it. Yech. */
95 *l = strtol(arg, &endp, 0);
97 return arg_bad("'%s' is not a number", arg);
99 return arg_bad("'%s' is out of range", arg);
103 char *opt_set_ulongval(const char *arg, unsigned long *ul)
108 err = opt_set_longval(arg, &l);
113 return arg_bad("'%s' is negative but destination is unsigned", arg);
117 char *opt_inc_intval(int *i)
123 /* Display version string. */
124 char *opt_version_and_exit(const char *version)
126 printf("%s\n", version);
127 /* Don't have valgrind complain! */
132 char *opt_usage_and_exit(const char *extra)
134 char *usage = opt_usage(opt_argv0, extra);
136 /* Don't have valgrind complain! */
142 void opt_show_bool(char buf[OPT_SHOW_LEN], const bool *b)
144 strncpy(buf, *b ? "true" : "false", OPT_SHOW_LEN);
147 void opt_show_invbool(char buf[OPT_SHOW_LEN], const bool *b)
149 strncpy(buf, *b ? "false" : "true", OPT_SHOW_LEN);
152 void opt_show_charp(char buf[OPT_SHOW_LEN], char *const *p)
154 size_t len = strlen(*p);
156 if (len > OPT_SHOW_LEN - 2)
157 len = OPT_SHOW_LEN - 2;
158 strncpy(buf+1, *p, len);
160 if (len < OPT_SHOW_LEN - 2)
164 /* Show an integer value, various forms. */
165 void opt_show_intval(char buf[OPT_SHOW_LEN], const int *i)
167 snprintf(buf, OPT_SHOW_LEN, "%i", *i);
170 void opt_show_uintval(char buf[OPT_SHOW_LEN], const unsigned int *ui)
172 snprintf(buf, OPT_SHOW_LEN, "%u", *ui);
175 void opt_show_longval(char buf[OPT_SHOW_LEN], const long *l)
177 snprintf(buf, OPT_SHOW_LEN, "%li", *l);
180 void opt_show_ulongval(char buf[OPT_SHOW_LEN], const unsigned long *ul)
182 snprintf(buf, OPT_SHOW_LEN, "%lu", *ul);
185 /* a helper function that multiplies out an argument's kMGTPE suffix in the
186 * long long int range, and perform checks common to all integer destinations.
188 * The base will be either 1000 or 1024, corresponding with the '_si' and
192 static char *set_llong_with_suffix(const char *arg, long long *ll,
193 const long long base)
197 return arg_bad("'%s' (an empty string) is not a number", arg);
200 *ll = strtoll(arg, &endp, 0);
202 return arg_bad("'%s' is out of range", arg);
204 /*The string continues with non-digits. If there is just one
205 letter and it is a known multiplier suffix, use it.*/
207 return arg_bad("'%s' is not a number (suffix too long)", arg);
220 mul = base * base * base;
224 mul = base * base * base * base;
227 mul = base * base * base * base * base;
230 mul = base * base * base * base * base * base;
232 /* This is as far as we can go in 64 bits ('E' is 2 ^ 60) */
234 return arg_bad("'%s' is not a number (unknown suffix)",
237 if (*ll > LLONG_MAX / mul || *ll < LLONG_MIN / mul)
238 return arg_bad("'%s' is out of range", arg);
244 /* Middle layer helpers that perform bounds checks for specific target sizes
247 static char * set_ulonglong_with_suffix(const char *arg, unsigned long long *ull,
251 char *err = set_llong_with_suffix(arg, &ll, base);
255 return arg_bad("'%s' is negative but destination is unsigned", arg);
260 static char * set_long_with_suffix(const char *arg, long *l, const long base)
263 char *err = set_llong_with_suffix(arg, &ll, base);
264 if (err != NULL) /*an error*/
268 /* Beware truncation, but don't generate untestable code. */
269 if (sizeof(*l) != sizeof(ll) && *l != ll)
270 return arg_bad("value '%s' does not fit into a long", arg);
274 static char * set_ulong_with_suffix(const char *arg, unsigned long *ul, const long base)
277 char *err = set_llong_with_suffix(arg, &ll, base);
281 return arg_bad("'%s' is negative but destination is unsigned", arg);
283 /* Beware truncation, but don't generate untestable code. */
284 if (sizeof(*ul) != sizeof(ll) && *ul != ll)
285 return arg_bad("value '%s' does not fit into an unsigned long", arg);
289 static char * set_int_with_suffix(const char *arg, int *i, const long base)
292 char *err = set_llong_with_suffix(arg, &ll, base);
293 if (err != NULL) /*an error*/
298 return arg_bad("value '%s' does not fit into an int", arg);
302 static char * set_uint_with_suffix(const char *arg, unsigned int *u, const long base)
305 char *err = set_llong_with_suffix(arg, &ll, base);
309 return arg_bad("'%s' is negative but destination is unsigned", arg);
312 return arg_bad("value '%s' does not fit into an unsigned int", arg);
316 /*Set an integer, with decimal or binary suffixes.
317 The accepted suffixes are k/K, M/m, G/g, T, P, E.
319 The *_bi functions multiply the numeric value by a power of 1024, while the
320 *_si functions multiply by a power of 1000.
323 char * opt_set_ulonglongval_bi(const char *arg, unsigned long long *ll)
325 return set_ulonglong_with_suffix(arg, ll, 1024);
328 char * opt_set_ulonglongval_si(const char *arg, unsigned long long *ll)
330 return set_ulonglong_with_suffix(arg, ll, 1000);
333 char * opt_set_longlongval_bi(const char *arg, long long *ll)
335 return set_llong_with_suffix(arg, ll, 1024);
338 char * opt_set_longlongval_si(const char *arg, long long *ll)
340 return set_llong_with_suffix(arg, ll, 1000);
343 char * opt_set_longval_bi(const char *arg, long *l)
345 return set_long_with_suffix(arg, l, 1024);
348 char * opt_set_longval_si(const char *arg, long *l)
350 return set_long_with_suffix(arg, l, 1000);
353 char * opt_set_ulongval_bi(const char *arg, unsigned long *ul)
355 return set_ulong_with_suffix(arg, ul, 1024);
358 char * opt_set_ulongval_si(const char *arg, unsigned long *ul)
360 return set_ulong_with_suffix(arg, ul, 1000);
363 char * opt_set_intval_bi(const char *arg, int *i)
365 return set_int_with_suffix(arg, i, 1024);
368 char * opt_set_intval_si(const char *arg, int *i)
370 return set_int_with_suffix(arg, i, 1000);
373 char * opt_set_uintval_bi(const char *arg, unsigned int *u)
375 return set_uint_with_suffix(arg, u, 1024);
378 char * opt_set_uintval_si(const char *arg, unsigned int *u)
380 return set_uint_with_suffix(arg, u, 1000);
383 /*static helpers for showing values with kMGTPE suffixes. In this case there
384 are separate but essentially identical functions for signed and unsigned
385 values, so that unsigned values greater than LLONG_MAX get suffixes.
387 static void show_llong_with_suffix(char buf[OPT_SHOW_LEN], long long ll,
388 const long long base)
390 const char *suffixes = "kMGTPE";
393 /*zero is special because everything divides it (you'd get "0E")*/
394 snprintf(buf, OPT_SHOW_LEN, "0");
397 for (i = 0; i < strlen(suffixes); i++){
398 long long tmp = ll / base;
399 if (tmp * base != ll)
404 snprintf(buf, OPT_SHOW_LEN, "%lld", ll);
406 snprintf(buf, OPT_SHOW_LEN, "%lld%c", ll, suffixes[i - 1]);
409 static void show_ullong_with_suffix(char buf[OPT_SHOW_LEN], unsigned long long ull,
412 const char *suffixes = "kMGTPE";
415 /*zero is special because everything divides it (you'd get "0E")*/
416 snprintf(buf, OPT_SHOW_LEN, "0");
419 for (i = 0; i < strlen(suffixes); i++){
420 unsigned long long tmp = ull / base;
421 if (tmp * base != ull)
426 snprintf(buf, OPT_SHOW_LEN, "%llu", ull);
428 snprintf(buf, OPT_SHOW_LEN, "%llu%c", ull, suffixes[i - 1]);
432 void opt_show_intval_bi(char buf[OPT_SHOW_LEN], const int *x)
434 show_llong_with_suffix(buf, *x, 1024);
437 void opt_show_longval_bi(char buf[OPT_SHOW_LEN], const long *x)
439 show_llong_with_suffix(buf, *x, 1024);
442 void opt_show_longlongval_bi(char buf[OPT_SHOW_LEN], const long long *x)
444 show_llong_with_suffix(buf, *x, 1024);
448 void opt_show_uintval_bi(char buf[OPT_SHOW_LEN], const unsigned int *x)
450 show_ullong_with_suffix(buf, (unsigned long long) *x, 1024);
453 void opt_show_ulongval_bi(char buf[OPT_SHOW_LEN], const unsigned long *x)
455 show_ullong_with_suffix(buf, (unsigned long long) *x, 1024);
458 void opt_show_ulonglongval_bi(char buf[OPT_SHOW_LEN], const unsigned long long *x)
460 show_ullong_with_suffix(buf, (unsigned long long) *x, 1024);
464 void opt_show_intval_si(char buf[OPT_SHOW_LEN], const int *x)
466 show_llong_with_suffix(buf, (long long) *x, 1000);
469 void opt_show_longval_si(char buf[OPT_SHOW_LEN], const long *x)
471 show_llong_with_suffix(buf, (long long) *x, 1000);
474 void opt_show_longlongval_si(char buf[OPT_SHOW_LEN], const long long *x)
476 show_llong_with_suffix(buf, *x, 1000);
480 void opt_show_uintval_si(char buf[OPT_SHOW_LEN], const unsigned int *x)
482 show_ullong_with_suffix(buf, (unsigned long long) *x, 1000);
485 void opt_show_ulongval_si(char buf[OPT_SHOW_LEN], const unsigned long *x)
487 show_ullong_with_suffix(buf, (unsigned long long) *x, 1000);
490 void opt_show_ulonglongval_si(char buf[OPT_SHOW_LEN], const unsigned long long *x)
492 show_ullong_with_suffix(buf, (unsigned long long) *x, 1000);