1 /* Licensed under GPLv2+ - see LICENSE file for details */
2 #include <ccan/opt/opt.h>
3 #include <ccan/cast/cast.h>
13 /* Upper bound to sprintf this simple type? Each 3 bits < 1 digit. */
14 #define CHAR_SIZE(type) (((sizeof(type)*CHAR_BIT + 2) / 3) + 1)
16 /* FIXME: asprintf module? */
17 static char *arg_bad(const char *fmt, const char *arg)
19 char *str = malloc(strlen(fmt) + strlen(arg));
20 sprintf(str, fmt, arg);
24 char *opt_set_bool(bool *b)
30 char *opt_set_invbool(bool *b)
36 char *opt_set_bool_arg(const char *arg, bool *b)
38 if (!strcasecmp(arg, "yes") || !strcasecmp(arg, "true"))
39 return opt_set_bool(b);
40 if (!strcasecmp(arg, "no") || !strcasecmp(arg, "false"))
41 return opt_set_invbool(b);
43 return opt_invalid_argument(arg);
46 char *opt_set_invbool_arg(const char *arg, bool *b)
48 char *err = opt_set_bool_arg(arg, b);
56 char *opt_set_charp(const char *arg, char **p)
58 *p = cast_const(char *, arg);
62 /* Set an integer value, various forms.
63 FIXME: set to 1 on arg == NULL ? */
64 char *opt_set_intval(const char *arg, int *i)
67 char *err = opt_set_longval(arg, &l);
72 /* Beware truncation, but don't generate untestable code. */
73 if (sizeof(*i) != sizeof(l) && *i != l)
74 return arg_bad("value '%s' does not fit into an integer", arg);
78 char *opt_set_uintval(const char *arg, unsigned int *ui)
81 char *err = opt_set_intval(arg, &i);
86 return arg_bad("'%s' is negative but destination is unsigned", arg);
91 char *opt_set_longval(const char *arg, long *l)
95 /* This is how the manpage says to do it. Yech. */
97 *l = strtol(arg, &endp, 0);
99 return arg_bad("'%s' is not a number", arg);
101 return arg_bad("'%s' is out of range", arg);
105 char *opt_set_ulongval(const char *arg, unsigned long *ul)
110 err = opt_set_longval(arg, &l);
115 return arg_bad("'%s' is negative but destination is unsigned", arg);
119 char *opt_set_floatval(const char *arg, float *f)
124 err = opt_set_doubleval(arg, &d);
130 return arg_bad("'%s' is out of range", arg);
135 void opt_show_floatval(char buf[OPT_SHOW_LEN], const float *f)
138 opt_show_doubleval(buf, &d);
141 char *opt_set_doubleval(const char *arg, double *d)
145 /* This is how the manpage says to do it. Yech. */
147 /* Don't assume strtof */
148 *d = strtod(arg, &endp);
149 if (*endp || !arg[0])
150 return arg_bad("'%s' is not a number", arg);
152 return arg_bad("'%s' is out of range", arg);
157 void opt_show_doubleval(char buf[OPT_SHOW_LEN], const double *d)
159 snprintf(buf, OPT_SHOW_LEN, "%f", *d);
162 char *opt_inc_intval(int *i)
168 /* Display version string. */
169 char *opt_version_and_exit(const char *version)
171 printf("%s\n", version);
172 /* Don't have valgrind complain! */
177 char *opt_usage_and_exit(const char *extra)
179 char *usage = opt_usage(opt_argv0, extra);
181 /* Don't have valgrind complain! */
182 opt_alloc.free(usage);
187 void opt_show_bool(char buf[OPT_SHOW_LEN], const bool *b)
189 strncpy(buf, *b ? "true" : "false", OPT_SHOW_LEN);
192 void opt_show_invbool(char buf[OPT_SHOW_LEN], const bool *b)
194 strncpy(buf, *b ? "false" : "true", OPT_SHOW_LEN);
197 void opt_show_charp(char buf[OPT_SHOW_LEN], char *const *p)
199 size_t len = strlen(*p);
201 if (len > OPT_SHOW_LEN - 2)
202 len = OPT_SHOW_LEN - 2;
203 strncpy(buf+1, *p, len);
205 if (len < OPT_SHOW_LEN - 2)
209 /* Show an integer value, various forms. */
210 void opt_show_intval(char buf[OPT_SHOW_LEN], const int *i)
212 snprintf(buf, OPT_SHOW_LEN, "%i", *i);
215 void opt_show_uintval(char buf[OPT_SHOW_LEN], const unsigned int *ui)
217 snprintf(buf, OPT_SHOW_LEN, "%u", *ui);
220 void opt_show_longval(char buf[OPT_SHOW_LEN], const long *l)
222 snprintf(buf, OPT_SHOW_LEN, "%li", *l);
225 void opt_show_ulongval(char buf[OPT_SHOW_LEN], const unsigned long *ul)
227 snprintf(buf, OPT_SHOW_LEN, "%lu", *ul);
230 /* a helper function that multiplies out an argument's kMGTPE suffix in the
231 * long long int range, and perform checks common to all integer destinations.
233 * The base will be either 1000 or 1024, corresponding with the '_si' and
237 static char *set_llong_with_suffix(const char *arg, long long *ll,
238 const long long base)
242 return arg_bad("'%s' (an empty string) is not a number", arg);
245 *ll = strtoll(arg, &endp, 0);
247 return arg_bad("'%s' is out of range", arg);
249 /*The string continues with non-digits. If there is just one
250 letter and it is a known multiplier suffix, use it.*/
252 return arg_bad("'%s' is not a number (suffix too long)", arg);
265 mul = base * base * base;
269 mul = base * base * base * base;
272 mul = base * base * base * base * base;
275 mul = base * base * base * base * base * base;
277 /* This is as far as we can go in 64 bits ('E' is 2 ^ 60) */
279 return arg_bad("'%s' is not a number (unknown suffix)",
282 if (*ll > LLONG_MAX / mul || *ll < LLONG_MIN / mul)
283 return arg_bad("'%s' is out of range", arg);
289 /* Middle layer helpers that perform bounds checks for specific target sizes
292 static char * set_ulonglong_with_suffix(const char *arg, unsigned long long *ull,
296 char *err = set_llong_with_suffix(arg, &ll, base);
300 return arg_bad("'%s' is negative but destination is unsigned", arg);
305 static char * set_long_with_suffix(const char *arg, long *l, const long base)
308 char *err = set_llong_with_suffix(arg, &ll, base);
309 if (err != NULL) /*an error*/
313 /* Beware truncation, but don't generate untestable code. */
314 if (sizeof(*l) != sizeof(ll) && *l != ll)
315 return arg_bad("value '%s' does not fit into a long", arg);
319 static char * set_ulong_with_suffix(const char *arg, unsigned long *ul, const long base)
322 char *err = set_llong_with_suffix(arg, &ll, base);
326 return arg_bad("'%s' is negative but destination is unsigned", arg);
328 /* Beware truncation, but don't generate untestable code. */
329 if (sizeof(*ul) != sizeof(ll) && *ul != ll)
330 return arg_bad("value '%s' does not fit into an unsigned long", arg);
334 static char * set_int_with_suffix(const char *arg, int *i, const long base)
337 char *err = set_llong_with_suffix(arg, &ll, base);
338 if (err != NULL) /*an error*/
343 return arg_bad("value '%s' does not fit into an int", arg);
347 static char * set_uint_with_suffix(const char *arg, unsigned int *u, const long base)
350 char *err = set_llong_with_suffix(arg, &ll, base);
354 return arg_bad("'%s' is negative but destination is unsigned", arg);
357 return arg_bad("value '%s' does not fit into an unsigned int", arg);
361 /*Set an integer, with decimal or binary suffixes.
362 The accepted suffixes are k/K, M/m, G/g, T, P, E.
364 The *_bi functions multiply the numeric value by a power of 1024, while the
365 *_si functions multiply by a power of 1000.
368 char * opt_set_ulonglongval_bi(const char *arg, unsigned long long *ll)
370 return set_ulonglong_with_suffix(arg, ll, 1024);
373 char * opt_set_ulonglongval_si(const char *arg, unsigned long long *ll)
375 return set_ulonglong_with_suffix(arg, ll, 1000);
378 char * opt_set_longlongval_bi(const char *arg, long long *ll)
380 return set_llong_with_suffix(arg, ll, 1024);
383 char * opt_set_longlongval_si(const char *arg, long long *ll)
385 return set_llong_with_suffix(arg, ll, 1000);
388 char * opt_set_longval_bi(const char *arg, long *l)
390 return set_long_with_suffix(arg, l, 1024);
393 char * opt_set_longval_si(const char *arg, long *l)
395 return set_long_with_suffix(arg, l, 1000);
398 char * opt_set_ulongval_bi(const char *arg, unsigned long *ul)
400 return set_ulong_with_suffix(arg, ul, 1024);
403 char * opt_set_ulongval_si(const char *arg, unsigned long *ul)
405 return set_ulong_with_suffix(arg, ul, 1000);
408 char * opt_set_intval_bi(const char *arg, int *i)
410 return set_int_with_suffix(arg, i, 1024);
413 char * opt_set_intval_si(const char *arg, int *i)
415 return set_int_with_suffix(arg, i, 1000);
418 char * opt_set_uintval_bi(const char *arg, unsigned int *u)
420 return set_uint_with_suffix(arg, u, 1024);
423 char * opt_set_uintval_si(const char *arg, unsigned int *u)
425 return set_uint_with_suffix(arg, u, 1000);
428 /*static helpers for showing values with kMGTPE suffixes. In this case there
429 are separate but essentially identical functions for signed and unsigned
430 values, so that unsigned values greater than LLONG_MAX get suffixes.
432 static void show_llong_with_suffix(char buf[OPT_SHOW_LEN], long long ll,
433 const long long base)
435 const char *suffixes = "kMGTPE";
438 /*zero is special because everything divides it (you'd get "0E")*/
439 snprintf(buf, OPT_SHOW_LEN, "0");
442 for (i = 0; i < strlen(suffixes); i++){
443 long long tmp = ll / base;
444 if (tmp * base != ll)
449 snprintf(buf, OPT_SHOW_LEN, "%"PRId64, (int64_t)ll);
451 snprintf(buf, OPT_SHOW_LEN, "%"PRId64"%c", (int64_t)ll, suffixes[i - 1]);
454 static void show_ullong_with_suffix(char buf[OPT_SHOW_LEN], unsigned long long ull,
457 const char *suffixes = "kMGTPE";
460 /*zero is special because everything divides it (you'd get "0E")*/
461 snprintf(buf, OPT_SHOW_LEN, "0");
464 for (i = 0; i < strlen(suffixes); i++){
465 unsigned long long tmp = ull / base;
466 if (tmp * base != ull)
471 snprintf(buf, OPT_SHOW_LEN, "%"PRIu64, (uint64_t)ull);
473 snprintf(buf, OPT_SHOW_LEN, "%"PRIu64"%c", (uint64_t)ull, suffixes[i - 1]);
477 void opt_show_intval_bi(char buf[OPT_SHOW_LEN], const int *x)
479 show_llong_with_suffix(buf, *x, 1024);
482 void opt_show_longval_bi(char buf[OPT_SHOW_LEN], const long *x)
484 show_llong_with_suffix(buf, *x, 1024);
487 void opt_show_longlongval_bi(char buf[OPT_SHOW_LEN], const long long *x)
489 show_llong_with_suffix(buf, *x, 1024);
493 void opt_show_uintval_bi(char buf[OPT_SHOW_LEN], const unsigned int *x)
495 show_ullong_with_suffix(buf, (unsigned long long) *x, 1024);
498 void opt_show_ulongval_bi(char buf[OPT_SHOW_LEN], const unsigned long *x)
500 show_ullong_with_suffix(buf, (unsigned long long) *x, 1024);
503 void opt_show_ulonglongval_bi(char buf[OPT_SHOW_LEN], const unsigned long long *x)
505 show_ullong_with_suffix(buf, (unsigned long long) *x, 1024);
509 void opt_show_intval_si(char buf[OPT_SHOW_LEN], const int *x)
511 show_llong_with_suffix(buf, (long long) *x, 1000);
514 void opt_show_longval_si(char buf[OPT_SHOW_LEN], const long *x)
516 show_llong_with_suffix(buf, (long long) *x, 1000);
519 void opt_show_longlongval_si(char buf[OPT_SHOW_LEN], const long long *x)
521 show_llong_with_suffix(buf, *x, 1000);
525 void opt_show_uintval_si(char buf[OPT_SHOW_LEN], const unsigned int *x)
527 show_ullong_with_suffix(buf, (unsigned long long) *x, 1000);
530 void opt_show_ulongval_si(char buf[OPT_SHOW_LEN], const unsigned long *x)
532 show_ullong_with_suffix(buf, (unsigned long long) *x, 1000);
535 void opt_show_ulonglongval_si(char buf[OPT_SHOW_LEN], const unsigned long long *x)
537 show_ullong_with_suffix(buf, (unsigned long long) *x, 1000);