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 static char *arg_bad(const char *fmt, const char *arg)
19 char *str = opt_alloc.alloc(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 /*allow true infinity via --foo=INF, while avoiding isinf() from math.h
131 because it wasn't standard 25 years ago.*/
132 double inf = 1e300 * 1e300; /*direct 1e600 annoys -Woverflow*/
133 if ((d > FLT_MAX || d < -FLT_MAX) && d != inf && d != -inf)
134 return arg_bad("'%s' is out of range for a 32 bit float", arg);
135 if (d != 0 && *f == 0)
136 return arg_bad("'%s' is out of range (truncated to zero)", arg);
141 void opt_show_floatval(char *buf, size_t len, const float *f)
144 opt_show_doubleval(buf, len, &d);
147 char *opt_set_doubleval(const char *arg, double *d)
151 /* This is how the manpage says to do it. Yech. */
153 /* Don't assume strtof */
154 *d = strtod(arg, &endp);
155 if (*endp || !arg[0])
156 return arg_bad("'%s' is not a number", arg);
158 return arg_bad("'%s' is out of range", arg);
163 void opt_show_doubleval(char *buf, size_t len, const double *d)
165 snprintf(buf, len, "%f", *d);
168 char *opt_inc_intval(int *i)
174 char *opt_dec_intval(int *i)
180 /* Display version string. */
181 char *opt_version_and_exit(const char *version)
183 printf("%s\n", version);
184 /* Don't have valgrind complain! */
189 char *opt_usage_and_exit(const char *extra)
191 char *usage = opt_usage(opt_argv0, extra);
193 /* Don't have valgrind complain! */
194 opt_alloc.free(usage);
199 void opt_show_bool(char *buf, size_t len, const bool *b)
201 strncpy(buf, *b ? "true" : "false", len);
204 void opt_show_invbool(char *buf, size_t len, const bool *b)
206 strncpy(buf, *b ? "false" : "true", len);
209 void opt_show_charp(char *buf, size_t len, char *const *p)
212 size_t plen = strlen(*p);
218 strncpy(buf+1, *p, plen);
224 strncpy(buf, "(nil)", len);
228 /* Show an integer value, various forms. */
229 void opt_show_intval(char *buf, size_t len, const int *i)
231 snprintf(buf, len, "%i", *i);
234 void opt_show_uintval(char *buf, size_t len, const unsigned int *ui)
236 snprintf(buf, len, "%u", *ui);
239 void opt_show_longval(char *buf, size_t len, const long *l)
241 snprintf(buf, len, "%li", *l);
244 void opt_show_ulongval(char *buf, size_t len, const unsigned long *ul)
246 snprintf(buf, len, "%lu", *ul);
249 /* a helper function that multiplies out an argument's kMGTPE suffix in the
250 * long long int range, and perform checks common to all integer destinations.
252 * The base will be either 1000 or 1024, corresponding with the '_si' and
256 static char *set_llong_with_suffix(const char *arg, long long *ll,
257 const long long base)
262 return arg_bad("'%s' (an empty string) is not a number", arg);
265 *ll = strtoll(arg, &endp, 0);
267 return arg_bad("'%s' is out of range", arg);
269 /*The string continues with non-digits. If there is just one
270 letter and it is a known multiplier suffix, use it.*/
272 return arg_bad("'%s' is not a number (suffix too long)", arg);
285 mul = base * base * base;
289 mul = base * base * base * base;
292 mul = base * base * base * base * base;
295 mul = base * base * base * base * base * base;
297 /* This is as far as we can go in 64 bits ('E' is 2 ^ 60) */
299 return arg_bad("'%s' is not a number (unknown suffix)",
302 if (*ll > LLONG_MAX / mul || *ll < LLONG_MIN / mul)
303 return arg_bad("'%s' is out of range", arg);
309 /* Middle layer helpers that perform bounds checks for specific target sizes
312 static char * set_ulonglong_with_suffix(const char *arg, unsigned long long *ull,
316 char *err = set_llong_with_suffix(arg, &ll, base);
320 return arg_bad("'%s' is negative but destination is unsigned", arg);
325 static char * set_long_with_suffix(const char *arg, long *l, const long base)
328 char *err = set_llong_with_suffix(arg, &ll, base);
329 if (err != NULL) /*an error*/
333 /* Beware truncation, but don't generate untestable code. */
334 if (sizeof(*l) != sizeof(ll) && *l != ll)
335 return arg_bad("value '%s' does not fit into a long", arg);
339 static char * set_ulong_with_suffix(const char *arg, unsigned long *ul, const long base)
342 char *err = set_llong_with_suffix(arg, &ll, base);
346 return arg_bad("'%s' is negative but destination is unsigned", arg);
348 /* Beware truncation, but don't generate untestable code. */
349 if (sizeof(*ul) != sizeof(ll) && *ul != ll)
350 return arg_bad("value '%s' does not fit into an unsigned long", arg);
354 static char * set_int_with_suffix(const char *arg, int *i, const long base)
357 char *err = set_llong_with_suffix(arg, &ll, base);
358 if (err != NULL) /*an error*/
363 return arg_bad("value '%s' does not fit into an int", arg);
367 static char * set_uint_with_suffix(const char *arg, unsigned int *u, const long base)
370 char *err = set_llong_with_suffix(arg, &ll, base);
374 return arg_bad("'%s' is negative but destination is unsigned", arg);
377 return arg_bad("value '%s' does not fit into an unsigned int", arg);
381 /*Set an integer, with decimal or binary suffixes.
382 The accepted suffixes are k/K, M/m, G/g, T, P, E.
384 The *_bi functions multiply the numeric value by a power of 1024, while the
385 *_si functions multiply by a power of 1000.
388 char * opt_set_ulonglongval_bi(const char *arg, unsigned long long *ll)
390 return set_ulonglong_with_suffix(arg, ll, 1024);
393 char * opt_set_ulonglongval_si(const char *arg, unsigned long long *ll)
395 return set_ulonglong_with_suffix(arg, ll, 1000);
398 char * opt_set_longlongval_bi(const char *arg, long long *ll)
400 return set_llong_with_suffix(arg, ll, 1024);
403 char * opt_set_longlongval_si(const char *arg, long long *ll)
405 return set_llong_with_suffix(arg, ll, 1000);
408 char * opt_set_longval_bi(const char *arg, long *l)
410 return set_long_with_suffix(arg, l, 1024);
413 char * opt_set_longval_si(const char *arg, long *l)
415 return set_long_with_suffix(arg, l, 1000);
418 char * opt_set_ulongval_bi(const char *arg, unsigned long *ul)
420 return set_ulong_with_suffix(arg, ul, 1024);
423 char * opt_set_ulongval_si(const char *arg, unsigned long *ul)
425 return set_ulong_with_suffix(arg, ul, 1000);
428 char * opt_set_intval_bi(const char *arg, int *i)
430 return set_int_with_suffix(arg, i, 1024);
433 char * opt_set_intval_si(const char *arg, int *i)
435 return set_int_with_suffix(arg, i, 1000);
438 char * opt_set_uintval_bi(const char *arg, unsigned int *u)
440 return set_uint_with_suffix(arg, u, 1024);
443 char * opt_set_uintval_si(const char *arg, unsigned int *u)
445 return set_uint_with_suffix(arg, u, 1000);
448 /*static helpers for showing values with kMGTPE suffixes. In this case there
449 are separate but essentially identical functions for signed and unsigned
450 values, so that unsigned values greater than LLONG_MAX get suffixes.
452 static void show_llong_with_suffix(char *buf, size_t len, long long ll,
453 const long long base)
455 const char *suffixes = "kMGTPE";
458 /*zero is special because everything divides it (you'd get "0E")*/
459 snprintf(buf, len, "0");
462 for (i = 0; i < strlen(suffixes); i++){
463 long long tmp = ll / base;
464 if (tmp * base != ll)
469 snprintf(buf, len, "%"PRId64, (int64_t)ll);
471 snprintf(buf, len, "%"PRId64"%c", (int64_t)ll, suffixes[i - 1]);
474 static void show_ullong_with_suffix(char *buf, size_t len,
475 unsigned long long ull,
478 const char *suffixes = "kMGTPE";
481 /*zero is special because everything divides it (you'd get "0E")*/
482 snprintf(buf, len, "0");
485 for (i = 0; i < strlen(suffixes); i++){
486 unsigned long long tmp = ull / base;
487 if (tmp * base != ull)
492 snprintf(buf, len, "%"PRIu64, (uint64_t)ull);
494 snprintf(buf, len, "%"PRIu64"%c", (uint64_t)ull, suffixes[i - 1]);
498 void opt_show_intval_bi(char *buf, size_t len, const int *x)
500 show_llong_with_suffix(buf, len, *x, 1024);
503 void opt_show_longval_bi(char *buf, size_t len, const long *x)
505 show_llong_with_suffix(buf, len, *x, 1024);
508 void opt_show_longlongval_bi(char *buf, size_t len, const long long *x)
510 show_llong_with_suffix(buf, len, *x, 1024);
514 void opt_show_uintval_bi(char *buf, size_t len, const unsigned int *x)
516 show_ullong_with_suffix(buf, len, (unsigned long long) *x, 1024);
519 void opt_show_ulongval_bi(char *buf, size_t len, const unsigned long *x)
521 show_ullong_with_suffix(buf, len, (unsigned long long) *x, 1024);
524 void opt_show_ulonglongval_bi(char *buf, size_t len, const unsigned long long *x)
526 show_ullong_with_suffix(buf, len, (unsigned long long) *x, 1024);
530 void opt_show_intval_si(char *buf, size_t len, const int *x)
532 show_llong_with_suffix(buf, len, (long long) *x, 1000);
535 void opt_show_longval_si(char *buf, size_t len, const long *x)
537 show_llong_with_suffix(buf, len, (long long) *x, 1000);
540 void opt_show_longlongval_si(char *buf, size_t len, const long long *x)
542 show_llong_with_suffix(buf, len, *x, 1000);
546 void opt_show_uintval_si(char *buf, size_t len, const unsigned int *x)
548 show_ullong_with_suffix(buf, len, (unsigned long long) *x, 1000);
551 void opt_show_ulongval_si(char *buf, size_t len, const unsigned long *x)
553 show_ullong_with_suffix(buf, len, (unsigned long long) *x, 1000);
556 void opt_show_ulonglongval_si(char *buf, size_t len, const unsigned long long *x)
558 show_ullong_with_suffix(buf, len, (unsigned long long) *x, 1000);