1 /* Licensed under GPLv2+ - see LICENSE file for details */
2 #include <ccan/opt/opt.h>
3 #include <ccan/cast/cast.h>
14 /* Upper bound to sprintf this simple type? Each 3 bits < 1 digit. */
15 #define CHAR_SIZE(type) (((sizeof(type)*CHAR_BIT + 2) / 3) + 1)
17 /* FIXME: asprintf module? */
18 static char *arg_bad(const char *fmt, const char *arg)
20 char *str = malloc(strlen(fmt) + strlen(arg));
21 sprintf(str, fmt, arg);
25 char *opt_set_bool(bool *b)
31 char *opt_set_invbool(bool *b)
37 char *opt_set_bool_arg(const char *arg, bool *b)
39 if (!strcasecmp(arg, "yes") || !strcasecmp(arg, "true"))
40 return opt_set_bool(b);
41 if (!strcasecmp(arg, "no") || !strcasecmp(arg, "false"))
42 return opt_set_invbool(b);
44 return opt_invalid_argument(arg);
47 char *opt_set_invbool_arg(const char *arg, bool *b)
49 char *err = opt_set_bool_arg(arg, b);
57 char *opt_set_charp(const char *arg, char **p)
59 *p = cast_const(char *, arg);
63 /* Set an integer value, various forms.
64 FIXME: set to 1 on arg == NULL ? */
65 char *opt_set_intval(const char *arg, int *i)
68 char *err = opt_set_longval(arg, &l);
73 /* Beware truncation, but don't generate untestable code. */
74 if (sizeof(*i) != sizeof(l) && *i != l)
75 return arg_bad("value '%s' does not fit into an integer", arg);
79 char *opt_set_uintval(const char *arg, unsigned int *ui)
82 char *err = opt_set_intval(arg, &i);
87 return arg_bad("'%s' is negative but destination is unsigned", arg);
92 char *opt_set_longval(const char *arg, long *l)
96 /* This is how the manpage says to do it. Yech. */
98 *l = strtol(arg, &endp, 0);
100 return arg_bad("'%s' is not a number", arg);
102 return arg_bad("'%s' is out of range", arg);
106 char *opt_set_ulongval(const char *arg, unsigned long *ul)
111 err = opt_set_longval(arg, &l);
116 return arg_bad("'%s' is negative but destination is unsigned", arg);
120 char *opt_set_floatval(const char *arg, float *f)
125 err = opt_set_doubleval(arg, &d);
131 /*allow true infinity via --foo=INF, while avoiding isinf() from math.h
132 because it wasn't standard 25 years ago.*/
133 double inf = 1e300 * 1e300; /*direct 1e600 annoys -Woverflow*/
134 if ((d > FLT_MAX || d < -FLT_MAX) && d != inf && d != -inf)
135 return arg_bad("'%s' is out of range for a 32 bit float", arg);
136 if (d != 0 && *f == 0)
137 return arg_bad("'%s' is out of range (truncated to zero)", arg);
142 void opt_show_floatval(char buf[OPT_SHOW_LEN], const float *f)
145 opt_show_doubleval(buf, &d);
148 char *opt_set_doubleval(const char *arg, double *d)
152 /* This is how the manpage says to do it. Yech. */
154 /* Don't assume strtof */
155 *d = strtod(arg, &endp);
156 if (*endp || !arg[0])
157 return arg_bad("'%s' is not a number", arg);
159 return arg_bad("'%s' is out of range", arg);
164 void opt_show_doubleval(char buf[OPT_SHOW_LEN], const double *d)
166 snprintf(buf, OPT_SHOW_LEN, "%f", *d);
169 char *opt_inc_intval(int *i)
175 char *opt_dec_intval(int *i)
181 /* Display version string. */
182 char *opt_version_and_exit(const char *version)
184 printf("%s\n", version);
185 /* Don't have valgrind complain! */
190 char *opt_usage_and_exit(const char *extra)
192 char *usage = opt_usage(opt_argv0, extra);
194 /* Don't have valgrind complain! */
195 opt_alloc.free(usage);
200 void opt_show_bool(char buf[OPT_SHOW_LEN], const bool *b)
202 strncpy(buf, *b ? "true" : "false", OPT_SHOW_LEN);
205 void opt_show_invbool(char buf[OPT_SHOW_LEN], const bool *b)
207 strncpy(buf, *b ? "false" : "true", OPT_SHOW_LEN);
210 void opt_show_charp(char buf[OPT_SHOW_LEN], char *const *p)
213 size_t len = strlen(*p);
215 if (len > OPT_SHOW_LEN - 2)
216 len = OPT_SHOW_LEN - 2;
217 strncpy(buf+1, *p, len);
219 if (len < OPT_SHOW_LEN - 2)
223 strncpy(buf, "(nil)", OPT_SHOW_LEN);
227 /* Show an integer value, various forms. */
228 void opt_show_intval(char buf[OPT_SHOW_LEN], const int *i)
230 snprintf(buf, OPT_SHOW_LEN, "%i", *i);
233 void opt_show_uintval(char buf[OPT_SHOW_LEN], const unsigned int *ui)
235 snprintf(buf, OPT_SHOW_LEN, "%u", *ui);
238 void opt_show_longval(char buf[OPT_SHOW_LEN], const long *l)
240 snprintf(buf, OPT_SHOW_LEN, "%li", *l);
243 void opt_show_ulongval(char buf[OPT_SHOW_LEN], const unsigned long *ul)
245 snprintf(buf, OPT_SHOW_LEN, "%lu", *ul);
248 /* a helper function that multiplies out an argument's kMGTPE suffix in the
249 * long long int range, and perform checks common to all integer destinations.
251 * The base will be either 1000 or 1024, corresponding with the '_si' and
255 static char *set_llong_with_suffix(const char *arg, long long *ll,
256 const long long base)
261 return arg_bad("'%s' (an empty string) is not a number", arg);
264 *ll = strtoll(arg, &endp, 0);
266 return arg_bad("'%s' is out of range", arg);
268 /*The string continues with non-digits. If there is just one
269 letter and it is a known multiplier suffix, use it.*/
271 return arg_bad("'%s' is not a number (suffix too long)", arg);
284 mul = base * base * base;
288 mul = base * base * base * base;
291 mul = base * base * base * base * base;
294 mul = base * base * base * base * base * base;
296 /* This is as far as we can go in 64 bits ('E' is 2 ^ 60) */
298 return arg_bad("'%s' is not a number (unknown suffix)",
301 if (*ll > LLONG_MAX / mul || *ll < LLONG_MIN / mul)
302 return arg_bad("'%s' is out of range", arg);
308 /* Middle layer helpers that perform bounds checks for specific target sizes
311 static char * set_ulonglong_with_suffix(const char *arg, unsigned long long *ull,
315 char *err = set_llong_with_suffix(arg, &ll, base);
319 return arg_bad("'%s' is negative but destination is unsigned", arg);
324 static char * set_long_with_suffix(const char *arg, long *l, const long base)
327 char *err = set_llong_with_suffix(arg, &ll, base);
328 if (err != NULL) /*an error*/
332 /* Beware truncation, but don't generate untestable code. */
333 if (sizeof(*l) != sizeof(ll) && *l != ll)
334 return arg_bad("value '%s' does not fit into a long", arg);
338 static char * set_ulong_with_suffix(const char *arg, unsigned long *ul, const long base)
341 char *err = set_llong_with_suffix(arg, &ll, base);
345 return arg_bad("'%s' is negative but destination is unsigned", arg);
347 /* Beware truncation, but don't generate untestable code. */
348 if (sizeof(*ul) != sizeof(ll) && *ul != ll)
349 return arg_bad("value '%s' does not fit into an unsigned long", arg);
353 static char * set_int_with_suffix(const char *arg, int *i, const long base)
356 char *err = set_llong_with_suffix(arg, &ll, base);
357 if (err != NULL) /*an error*/
362 return arg_bad("value '%s' does not fit into an int", arg);
366 static char * set_uint_with_suffix(const char *arg, unsigned int *u, const long base)
369 char *err = set_llong_with_suffix(arg, &ll, base);
373 return arg_bad("'%s' is negative but destination is unsigned", arg);
376 return arg_bad("value '%s' does not fit into an unsigned int", arg);
380 /*Set an integer, with decimal or binary suffixes.
381 The accepted suffixes are k/K, M/m, G/g, T, P, E.
383 The *_bi functions multiply the numeric value by a power of 1024, while the
384 *_si functions multiply by a power of 1000.
387 char * opt_set_ulonglongval_bi(const char *arg, unsigned long long *ll)
389 return set_ulonglong_with_suffix(arg, ll, 1024);
392 char * opt_set_ulonglongval_si(const char *arg, unsigned long long *ll)
394 return set_ulonglong_with_suffix(arg, ll, 1000);
397 char * opt_set_longlongval_bi(const char *arg, long long *ll)
399 return set_llong_with_suffix(arg, ll, 1024);
402 char * opt_set_longlongval_si(const char *arg, long long *ll)
404 return set_llong_with_suffix(arg, ll, 1000);
407 char * opt_set_longval_bi(const char *arg, long *l)
409 return set_long_with_suffix(arg, l, 1024);
412 char * opt_set_longval_si(const char *arg, long *l)
414 return set_long_with_suffix(arg, l, 1000);
417 char * opt_set_ulongval_bi(const char *arg, unsigned long *ul)
419 return set_ulong_with_suffix(arg, ul, 1024);
422 char * opt_set_ulongval_si(const char *arg, unsigned long *ul)
424 return set_ulong_with_suffix(arg, ul, 1000);
427 char * opt_set_intval_bi(const char *arg, int *i)
429 return set_int_with_suffix(arg, i, 1024);
432 char * opt_set_intval_si(const char *arg, int *i)
434 return set_int_with_suffix(arg, i, 1000);
437 char * opt_set_uintval_bi(const char *arg, unsigned int *u)
439 return set_uint_with_suffix(arg, u, 1024);
442 char * opt_set_uintval_si(const char *arg, unsigned int *u)
444 return set_uint_with_suffix(arg, u, 1000);
447 /*static helpers for showing values with kMGTPE suffixes. In this case there
448 are separate but essentially identical functions for signed and unsigned
449 values, so that unsigned values greater than LLONG_MAX get suffixes.
451 static void show_llong_with_suffix(char buf[OPT_SHOW_LEN], long long ll,
452 const long long base)
454 const char *suffixes = "kMGTPE";
457 /*zero is special because everything divides it (you'd get "0E")*/
458 snprintf(buf, OPT_SHOW_LEN, "0");
461 for (i = 0; i < strlen(suffixes); i++){
462 long long tmp = ll / base;
463 if (tmp * base != ll)
468 snprintf(buf, OPT_SHOW_LEN, "%"PRId64, (int64_t)ll);
470 snprintf(buf, OPT_SHOW_LEN, "%"PRId64"%c", (int64_t)ll, suffixes[i - 1]);
473 static void show_ullong_with_suffix(char buf[OPT_SHOW_LEN], unsigned long long ull,
476 const char *suffixes = "kMGTPE";
479 /*zero is special because everything divides it (you'd get "0E")*/
480 snprintf(buf, OPT_SHOW_LEN, "0");
483 for (i = 0; i < strlen(suffixes); i++){
484 unsigned long long tmp = ull / base;
485 if (tmp * base != ull)
490 snprintf(buf, OPT_SHOW_LEN, "%"PRIu64, (uint64_t)ull);
492 snprintf(buf, OPT_SHOW_LEN, "%"PRIu64"%c", (uint64_t)ull, suffixes[i - 1]);
496 void opt_show_intval_bi(char buf[OPT_SHOW_LEN], const int *x)
498 show_llong_with_suffix(buf, *x, 1024);
501 void opt_show_longval_bi(char buf[OPT_SHOW_LEN], const long *x)
503 show_llong_with_suffix(buf, *x, 1024);
506 void opt_show_longlongval_bi(char buf[OPT_SHOW_LEN], const long long *x)
508 show_llong_with_suffix(buf, *x, 1024);
512 void opt_show_uintval_bi(char buf[OPT_SHOW_LEN], const unsigned int *x)
514 show_ullong_with_suffix(buf, (unsigned long long) *x, 1024);
517 void opt_show_ulongval_bi(char buf[OPT_SHOW_LEN], const unsigned long *x)
519 show_ullong_with_suffix(buf, (unsigned long long) *x, 1024);
522 void opt_show_ulonglongval_bi(char buf[OPT_SHOW_LEN], const unsigned long long *x)
524 show_ullong_with_suffix(buf, (unsigned long long) *x, 1024);
528 void opt_show_intval_si(char buf[OPT_SHOW_LEN], const int *x)
530 show_llong_with_suffix(buf, (long long) *x, 1000);
533 void opt_show_longval_si(char buf[OPT_SHOW_LEN], const long *x)
535 show_llong_with_suffix(buf, (long long) *x, 1000);
538 void opt_show_longlongval_si(char buf[OPT_SHOW_LEN], const long long *x)
540 show_llong_with_suffix(buf, *x, 1000);
544 void opt_show_uintval_si(char buf[OPT_SHOW_LEN], const unsigned int *x)
546 show_ullong_with_suffix(buf, (unsigned long long) *x, 1000);
549 void opt_show_ulongval_si(char buf[OPT_SHOW_LEN], const unsigned long *x)
551 show_ullong_with_suffix(buf, (unsigned long long) *x, 1000);
554 void opt_show_ulonglongval_si(char buf[OPT_SHOW_LEN], const unsigned long long *x)
556 show_ullong_with_suffix(buf, (unsigned long long) *x, 1000);